diff --git a/cloud_functions/src/alarmMissingVaas.ts b/cloud_functions/src/alarmMissingVaas.ts index 5f31cdc7..716e97ec 100644 --- a/cloud_functions/src/alarmMissingVaas.ts +++ b/cloud_functions/src/alarmMissingVaas.ts @@ -2,7 +2,12 @@ import { CHAIN_ID_TO_NAME, ChainId, ChainName } from '@certusone/wormhole-sdk'; import { MissingVaasByChain, commonGetMissingVaas } from './getMissingVaas'; import { assertEnvironmentVariable, formatAndSendToSlack, isVAASigned } from './utils'; import { ObservedMessage, ReobserveInfo, SlackInfo } from './types'; -import { NETWORK, explorerBlock, explorerTx } from '@wormhole-foundation/wormhole-monitor-common'; +import { + Environment, + getEnvironment, + explorerBlock, + explorerTx, +} from '@wormhole-foundation/wormhole-monitor-common'; import { Firestore } from 'firebase-admin/firestore'; interface EnqueuedVAAResponse { @@ -34,10 +39,7 @@ interface GovernedVAA { // The key is the vaaKey type GovernedVAAMap = Map; -const network: NETWORK = - assertEnvironmentVariable('NETWORK').toLowerCase() === 'mainnet' - ? NETWORK.MAINNET - : NETWORK.TESTNET; +const network: Environment = getEnvironment(); export async function alarmMissingVaas(req: any, res: any) { res.set('Access-Control-Allow-Origin', '*'); @@ -127,7 +129,7 @@ export async function alarmMissingVaas(req: any, res: any) { txhash: msg.txHash, vaaKey: vaaKey, }); - if (network === NETWORK.MAINNET) { + if (network === 'mainnet') { alarmSlackInfo.msg = formatMessage(msg); await formatAndSendToSlack(alarmSlackInfo); } @@ -323,7 +325,6 @@ async function alarmOldBlockTimes(latestTimes: LatestTimeByChain): Promise bannerTxt: 'Wormhole Missing VAA Alarm', msg: '', }; - const envNetwork: string = network === NETWORK.MAINNET ? 'mainnet' : 'testnet'; let alarmsToStore: AlarmedChainTime[] = []; // Read in the already alarmed chains. @@ -351,7 +352,7 @@ async function alarmOldBlockTimes(latestTimes: LatestTimeByChain): Promise const chainTime: Date = new Date(latestTime); const cName: string = CHAIN_ID_TO_NAME[chainId] as ChainName; const deltaTime: number = (now.getTime() - chainTime.getTime()) / (1000 * 60 * 60 * 24); - alarmSlackInfo.msg = `*Chain:* ${cName}(${chainId})\nThe ${envNetwork} watcher is behind by ${deltaTime} days.`; + alarmSlackInfo.msg = `*Chain:* ${cName}(${chainId})\nThe ${network} watcher is behind by ${deltaTime} days.`; await formatAndSendToSlack(alarmSlackInfo); alarmsToStore.push({ chain: chainId, alarmTime: now.toISOString() }); } diff --git a/common/src/consts.ts b/common/src/consts.ts index df764c56..ccb8e58e 100644 --- a/common/src/consts.ts +++ b/common/src/consts.ts @@ -31,15 +31,19 @@ import { coalesceChainName, } from '@certusone/wormhole-sdk'; -export enum NETWORK { - MAINNET, - TESTNET, -} +export type Environment = 'mainnet' | 'testnet' | 'devnet'; +export type Network = { + env: Environment; + endpoint: string; + name: string; + logo: string; + type: 'guardian' | 'cloudfunction'; +}; export const INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN: { - [key in NETWORK]: { [key in ChainName]?: string }; + [key in Environment]: { [key in ChainName]?: string }; } = { - [NETWORK.MAINNET]: { + ['mainnet']: { ethereum: '12959638', terra: '4810000', // not sure exactly but this should be before the first known message bsc: '9745450', @@ -66,7 +70,7 @@ export const INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN: { sei: '238594', wormchain: '4510119', // https://bigdipper.live/wormhole/transactions/4D861F1BE86325D227FA006CA2745BBC6748AF5B5E0811DE536D02792928472A }, }, - [NETWORK.TESTNET]: { + ['testnet']: { ethereum: '0', terra: '0', bsc: '0', @@ -93,6 +97,7 @@ export const INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN: { sei: '0', wormchain: '0', }, + ['devnet']: {}, }; export const TOKEN_BRIDGE_EMITTERS: { [key in ChainName]?: string } = { @@ -179,8 +184,8 @@ export type CHAIN_INFO = { explorerStem: string; }; -export const CHAIN_INFO_MAP: { [key in NETWORK]: { [key: string]: CHAIN_INFO } } = { - [NETWORK.MAINNET]: { +export const CHAIN_INFO_MAP: { [key in Environment]: { [key: string]: CHAIN_INFO } } = { + ['mainnet']: { 1: { name: 'solana', evm: false, @@ -371,7 +376,7 @@ export const CHAIN_INFO_MAP: { [key in NETWORK]: { [key: string]: CHAIN_INFO } } explorerStem: '', }, }, - [NETWORK.TESTNET]: { + ['testnet']: { // The chains not, currently, supported on testnet are commented out. 1: { name: 'solana', @@ -556,6 +561,7 @@ export const CHAIN_INFO_MAP: { [key in NETWORK]: { [key: string]: CHAIN_INFO } } // explorerStem: '', // }, }, + ['devnet']: {}, }; export const JUMP_GUARDIAN_ADDRESS = '58cc3ae5c097b213ce3c81979e1b9f9570746aa5'; diff --git a/common/src/explorer.ts b/common/src/explorer.ts index 2c3b1999..f21c9b59 100644 --- a/common/src/explorer.ts +++ b/common/src/explorer.ts @@ -31,10 +31,10 @@ import { CHAIN_ID_XPLA, } from '@certusone/wormhole-sdk'; import { base58 } from 'ethers/lib/utils'; -import { CHAIN_INFO_MAP, NETWORK } from './consts'; +import { CHAIN_INFO_MAP, Environment } from './consts'; -export const explorerBlock = (network: NETWORK, chainId: ChainId, block: string) => - network === NETWORK.MAINNET +export const explorerBlock = (network: Environment, chainId: ChainId, block: string) => + network === 'mainnet' ? chainId === CHAIN_ID_ETH ? `https://etherscan.io/block/${block}` : chainId === CHAIN_ID_BSC @@ -120,8 +120,8 @@ export const explorerBlock = (network: NETWORK, chainId: ChainId, block: string) ? `https://goerli.basescan.org/block/${block}` : ''; -export const explorerTx = (network: NETWORK, chainId: ChainId, tx: string) => - network === NETWORK.MAINNET +export const explorerTx = (network: Environment, chainId: ChainId, tx: string) => + network === 'mainnet' ? chainId === CHAIN_ID_ETH ? `https://etherscan.io/tx/${tx}` : chainId === CHAIN_ID_BSC @@ -212,7 +212,7 @@ export const explorerVaa = (network: string, key: string) => ? `https://wormholescan.io/#/tx/${key}` : `https://wormholescan.io/#/tx/${key}?network=TESTNET`; -export const getExplorerTxHash = (network: NETWORK, chain: ChainId, txHash: string) => { +export const getExplorerTxHash = (network: Environment, chain: ChainId, txHash: string) => { let explorerTxHash = ''; if (isCosmWasmChain(chain)) { explorerTxHash = txHash.slice(2); diff --git a/common/src/utils.ts b/common/src/utils.ts index d511de9e..bde08361 100644 --- a/common/src/utils.ts +++ b/common/src/utils.ts @@ -1,3 +1,5 @@ +import { Environment } from './consts'; + export async function sleep(timeout: number) { return new Promise((resolve) => setTimeout(resolve, timeout)); } @@ -13,3 +15,11 @@ export const padUint64 = (s: string): string => s.padStart(MAX_UINT_64.length, ' // make a bigtable row key for the `signedVAAs` table export const makeSignedVAAsRowKey = (chain: number, emitter: string, sequence: string): string => `${padUint16(chain.toString())}/${emitter}/${padUint64(sequence)}`; + +export function getEnvironment(): Environment { + const network: string = assertEnvironmentVariable('NETWORK').toLowerCase(); + if (network === 'mainnet' || network === 'testnet' || network === 'devnet') { + return network; + } + throw new Error(`Unknown network: ${network}`); +} diff --git a/dashboard/src/components/Accountant.tsx b/dashboard/src/components/Accountant.tsx index 99faf237..f319f761 100644 --- a/dashboard/src/components/Accountant.tsx +++ b/dashboard/src/components/Accountant.tsx @@ -7,7 +7,6 @@ import { Card, InputAdornment, LinearProgress, - Link, TextField, Tooltip, Typography, @@ -29,16 +28,13 @@ import useGetAccountantPendingTransfers, { } from '../hooks/useGetAccountantPendingTransfers'; import chainIdToName from '../utils/chainIdToName'; import { CHAIN_ICON_MAP, GUARDIAN_SET_3 } from '../utils/consts'; -import { - CHAIN_INFO_MAP, - explorerTx, - getExplorerTxHash, -} from '@wormhole-foundation/wormhole-monitor-common'; +import { CHAIN_INFO_MAP } from '@wormhole-foundation/wormhole-monitor-common'; import CollapsibleSection from './CollapsibleSection'; import Table from './Table'; import useTokenData, { TokenDataEntry } from '../hooks/useTokenData'; import numeral from 'numeral'; -import { GetNetworkFromEnv } from '../utils/GetNetworkFromEnv'; +import { useCurrentEnvironment } from '../contexts/NetworkContext'; +import { ExplorerTxHash } from './ExplorerTxHash'; type PendingTransferForAcct = PendingTransfer & { isEnqueuedInGov: boolean }; type AccountWithTokenData = Account & { @@ -143,23 +139,9 @@ const pendingTransferColumns = [ }), pendingTransferColumnHelper.accessor('data.0.tx_hash', { header: () => 'Tx', - cell: (info) => { - const tx = '0x' + Buffer.from(info.getValue(), 'base64').toString('hex'); - const chain = info.row.original.key.emitter_chain; - const network = GetNetworkFromEnv(); - const chainInfo = CHAIN_INFO_MAP[network][chain]; - if (!chainInfo) return tx; - const txHash = getExplorerTxHash(network, chainInfo.chainId, tx); - return ( - - {txHash} - - ); - }, + cell: (info) => ( + + ), }), pendingTransferColumnHelper.accessor('data.0.signatures', { header: () => 'Signatures', @@ -430,7 +412,7 @@ function Accountant({ governorInfo }: { governorInfo: CloudGovernorInfo }) { }, {} as { [chainId: number]: number }), [pendingTransferInfo] ); - const network = GetNetworkFromEnv(); + const network = useCurrentEnvironment(); return ( {assetAddr}; + const chainId: ChainId = chainInfo.chainId; + var tokenAddress: string = ''; + if (chainId === CHAIN_ID_ALGORAND || chainId === CHAIN_ID_NEAR || chainId === CHAIN_ID_TERRA2) { + return <>{assetAddr}; + } + try { + tokenAddress = tryHexToNativeAssetString( + assetAddr.slice(2), + CHAIN_INFO_MAP[network][chain]?.chainId + ); + } catch (e) { + console.log(e); + tokenAddress = assetAddr; + } + + const explorerString = chainInfo?.explorerStem; + const url = `${explorerString}/address/${tokenAddress}`; + return ( + + {tokenAddress} + + ); +} diff --git a/dashboard/src/components/ExplorerTxHash.tsx b/dashboard/src/components/ExplorerTxHash.tsx new file mode 100644 index 00000000..71703c2e --- /dev/null +++ b/dashboard/src/components/ExplorerTxHash.tsx @@ -0,0 +1,23 @@ +import { + CHAIN_INFO_MAP, + explorerTx, + getExplorerTxHash, +} from '@wormhole-foundation/wormhole-monitor-common'; +import { useCurrentEnvironment } from '../contexts/NetworkContext'; +import { Link } from '@mui/material'; + +export function ExplorerTxHash({ chain, rawTxHash }: { chain: number; rawTxHash: string }) { + const network = useCurrentEnvironment(); + const chainInfo = CHAIN_INFO_MAP[network][chain]; + if (!chainInfo) return <>{rawTxHash}; + const txHash = getExplorerTxHash(network, chainInfo.chainId, rawTxHash); + return ( + + {txHash} + + ); +} diff --git a/dashboard/src/components/Governor.tsx b/dashboard/src/components/Governor.tsx index 3933ff77..e99433f5 100644 --- a/dashboard/src/components/Governor.tsx +++ b/dashboard/src/components/Governor.tsx @@ -1,10 +1,3 @@ -import { - ChainId, - CHAIN_ID_ALGORAND, - CHAIN_ID_NEAR, - CHAIN_ID_TERRA2, - tryHexToNativeAssetString, -} from '@certusone/wormhole-sdk'; import { GovernorGetAvailableNotionalByChainResponse_Entry, GovernorGetEnqueuedVAAsResponse_Entry, @@ -37,16 +30,14 @@ import numeral from 'numeral'; import React, { useCallback, useMemo, useState } from 'react'; import useGovernorInfo from '../hooks/useGovernorInfo'; import chainIdToName from '../utils/chainIdToName'; -import { - CHAIN_INFO_MAP, - explorerTx, - getExplorerTxHash, -} from '@wormhole-foundation/wormhole-monitor-common'; +import { CHAIN_INFO_MAP } from '@wormhole-foundation/wormhole-monitor-common'; import CollapsibleSection from './CollapsibleSection'; import EnqueuedVAAChecker from './EnqueuedVAAChecker'; import Table from './Table'; import { CHAIN_ICON_MAP } from '../utils/consts'; -import { GetNetworkFromEnv } from '../utils/GetNetworkFromEnv'; +import { useCurrentEnvironment } from '../contexts/NetworkContext'; +import { ExplorerTxHash } from './ExplorerTxHash'; +import { ExplorerAssetURL } from './ExplorerAssetURL'; const calculatePercent = (notional: GovernorGetAvailableNotionalByChainResponse_Entry): number => { try { @@ -132,22 +123,9 @@ const enqueuedColumns = [ }), enqueuedColumnHelper.accessor('txHash', { header: () => 'Transaction Hash', - cell: (info) => { - const chain = info.row.original.emitterChain; - const network = GetNetworkFromEnv(); - const chainInfo = CHAIN_INFO_MAP[network][chain]; - if (!chainInfo) return info.getValue(); - const txHash = getExplorerTxHash(network, chainInfo.chainId, info.getValue()); - return ( - - {txHash} - - ); - }, + cell: (info) => ( + + ), }), enqueuedColumnHelper.accessor('releaseTime', { header: () => 'Release Time', @@ -170,38 +148,9 @@ const tokenColumns = [ }), tokenColumnHelper.accessor('originAddress', { header: () => 'Token', - cell: (info) => { - const chain = info.row.original.originChainId; - const network = GetNetworkFromEnv(); - const chainInfo = CHAIN_INFO_MAP[network][chain]; - if (!chainInfo) return info.getValue(); - const chainId: ChainId = chainInfo.chainId; - var tokenAddress: string = ''; - if ( - chainId === CHAIN_ID_ALGORAND || - chainId === CHAIN_ID_NEAR || - chainId === CHAIN_ID_TERRA2 - ) { - return info.getValue(); - } - try { - tokenAddress = tryHexToNativeAssetString( - info.getValue().slice(2), - CHAIN_INFO_MAP[network][chain]?.chainId - ); - } catch (e) { - console.log(e); - tokenAddress = info.getValue(); - } - - const explorerString = chainInfo?.explorerStem; - const url = `${explorerString}/address/${tokenAddress}`; - return ( - - {tokenAddress} - - ); - }, + cell: (info) => ( + + ), }), tokenColumnHelper.accessor('price', { header: () => Price, @@ -295,7 +244,7 @@ function Governor() { onGlobalFilterChange: setTokenGlobalFilter, onSortingChange: setTokenSorting, }); - const network = GetNetworkFromEnv(); + const network = useCurrentEnvironment(); return ( { try { @@ -175,7 +166,7 @@ const guardianHoldingColumns = [ {CHAIN_ICON_MAP[chainId] ? ( {CHAIN_INFO_MAP[GetNetworkFromEnv()][chainId].name} @@ -226,22 +217,9 @@ const enqueuedColumns = [ }), enqueuedColumnHelper.accessor('txHash', { header: () => 'Transaction Hash', - cell: (info) => { - const chain = info.row.original.emitterChain; - const network = GetNetworkFromEnv(); - const chainInfo = CHAIN_INFO_MAP[network][chain]; - if (!chainInfo) return info.getValue(); - const txHash = getExplorerTxHash(network, chainInfo.chainId, info.getValue()); - return ( - - {txHash} - - ); - }, + cell: (info) => ( + + ), }), enqueuedColumnHelper.accessor('releaseTime', { header: () => 'Release Time', @@ -264,37 +242,9 @@ const tokenColumns = [ }), tokenColumnHelper.accessor('originAddress', { header: () => 'Token', - cell: (info) => { - const chain = info.row.original.originChainId; - const network = GetNetworkFromEnv(); - const chainInfo = CHAIN_INFO_MAP[network][chain]; - if (!chainInfo) return info.getValue(); - const chainId: ChainId = chainInfo.chainId; - var tokenAddress: string = ''; - if ( - chainId === CHAIN_ID_ALGORAND || - chainId === CHAIN_ID_NEAR || - chainId === CHAIN_ID_TERRA2 - ) { - return info.getValue(); - } - try { - tokenAddress = tryHexToNativeAssetString( - info.getValue().slice(2), - CHAIN_INFO_MAP[network][chain]?.chainId - ); - } catch (e) { - tokenAddress = info.getValue(); - } - - const explorerString = chainInfo?.explorerStem; - const url = `${explorerString}/address/${tokenAddress}`; - return ( - - {tokenAddress} - - ); - }, + cell: (info) => ( + + ), }), tokenColumnHelper.accessor('price', { header: () => Price, @@ -409,7 +359,7 @@ function MainnetGovernor({ governorInfo }: { governorInfo: CloudGovernorInfo }) }, {} as ChainIdToEnqueuedCount), [governorInfo.enqueuedVAAs] ); - const network = GetNetworkFromEnv(); + const network = useCurrentEnvironment(); return ( = { }; function BlockDetail({ chain, message }: { chain: string; message: ObservedMessage }) { - const { currentNetwork } = useNetworkContext(); - const network: NETWORK = currentNetwork.env === 'mainnet' ? NETWORK.MAINNET : NETWORK.TESTNET; + const network: Environment = useCurrentEnvironment(); const vaaId = `${message.chain}/${message.emitter}/${message.seq}`; return ( @@ -113,7 +111,7 @@ function BlockDetail({ chain, message }: { chain: string; message: ObservedMessa gutterBottom > { const db = initDb(false); // Don't start watching - const network = getNetworkFromEnv(); + const network: Environment = getEnvironment(); const chain: ChainName = 'near'; const provider = await getNearProvider(network, NEAR_ARCHIVE_RPC); const fromBlock = Number( diff --git a/watcher/scripts/checkSolana.ts b/watcher/scripts/checkSolana.ts index 2a382c99..5151d913 100644 --- a/watcher/scripts/checkSolana.ts +++ b/watcher/scripts/checkSolana.ts @@ -2,11 +2,11 @@ import * as dotenv from 'dotenv'; dotenv.config(); import { SolanaWatcher } from '../src/watchers/SolanaWatcher'; -import { getNetworkFromEnv } from '../src/utils/environment'; +import { Environment, getEnvironment } from '@wormhole-foundation/wormhole-monitor-common'; // Temporary script to test SolanaWatcher for lookup addresses (async () => { - const network = getNetworkFromEnv(); + const network: Environment = getEnvironment(); const sw = new SolanaWatcher(network); const msgs = await sw.getMessagesForBlocks(245230133, 245230333); console.log(msgs); diff --git a/watcher/scripts/locateMessageGaps.ts b/watcher/scripts/locateMessageGaps.ts index 8e61aec0..76305cd1 100644 --- a/watcher/scripts/locateMessageGaps.ts +++ b/watcher/scripts/locateMessageGaps.ts @@ -1,19 +1,18 @@ import * as dotenv from 'dotenv'; dotenv.config(); import { ChainId, coalesceChainName } from '@certusone/wormhole-sdk'; -import { sleep } from '@wormhole-foundation/wormhole-monitor-common'; +import { Environment, getEnvironment, sleep } from '@wormhole-foundation/wormhole-monitor-common'; import { TIMEOUT } from '../src/consts'; import { BigtableDatabase } from '../src/databases/BigtableDatabase'; import { parseMessageId } from '../src/databases/utils'; import { makeFinalizedWatcher } from '../src/watchers/utils'; import { Watcher } from '../src/watchers/Watcher'; -import { getNetworkFromEnv } from '../src/utils/environment'; // This script checks for gaps in the message sequences for an emitter. // Ideally this shouldn't happen, but there seems to be an issue with Oasis, Karura, and Celo (async () => { - const network = getNetworkFromEnv(); + const network: Environment = getEnvironment(); const bt = new BigtableDatabase(); if (!bt.bigtable) { throw new Error('bigtable is undefined'); diff --git a/watcher/src/consts.ts b/watcher/src/consts.ts index de53ac89..3fe45f99 100644 --- a/watcher/src/consts.ts +++ b/watcher/src/consts.ts @@ -1,5 +1,5 @@ import { ChainName, CONTRACTS, Network } from '@certusone/wormhole-sdk/lib/cjs/utils/consts'; -import { NETWORK } from '@wormhole-foundation/wormhole-monitor-common'; +import { Environment } from '@wormhole-foundation/wormhole-monitor-common'; import { AxiosRequestConfig } from 'axios'; export const TIMEOUT = 0.5 * 1000; @@ -25,8 +25,8 @@ export const TIMEOUT = 0.5 * 1000; // Arbitrum // This node didn't work: 'https://arb1.arbitrum.io/rpc', -export const RPCS_BY_CHAIN: { [key in NETWORK]: { [key in ChainName]?: string } } = { - [NETWORK.MAINNET]: { +export const RPCS_BY_CHAIN: { [key in Environment]: { [key in ChainName]?: string } } = { + ['mainnet']: { ethereum: process.env.ETH_RPC, bsc: process.env.BSC_RPC || 'https://rpc.ankr.com/bsc', polygon: process.env.POLYGON_RPC || 'https://rpc.ankr.com/polygon', @@ -54,7 +54,7 @@ export const RPCS_BY_CHAIN: { [key in NETWORK]: { [key in ChainName]?: string } sei: process.env.SEI_RPC || 'https://sei-rest.brocha.in', // https://docs.sei.io/develop/resources wormchain: process.env.WORMCHAIN_RPC || 'https://wormchain-rpc.quickapi.com', }, - [NETWORK.TESTNET]: { + ['testnet']: { ethereum: process.env.ETH_RPC, bsc: process.env.BSC_RPC, polygon: process.env.POLYGON_RPC || 'https://rpc.ankr.com/polygon_mumbai', @@ -81,45 +81,58 @@ export const RPCS_BY_CHAIN: { [key in NETWORK]: { [key in ChainName]?: string } sei: process.env.SEI_RPC, wormchain: process.env.WORMCHAIN_RPC, }, + ['devnet']: {}, }; // The following is obsolete, but I'm leaving it here for now in case we need it later. // Separating for now so if we max out infura we can keep Polygon going -export const POLYGON_ROOT_CHAIN_INFO: { [key in NETWORK]: PolygonRootChainInfo } = { - [NETWORK.MAINNET]: { +export const POLYGON_ROOT_CHAIN_INFO: { [key in Environment]: PolygonRootChainInfo } = { + ['mainnet']: { address: '0x86E4Dc95c7FBdBf52e33D563BbDB00823894C287', rpc: 'https://rpc.ankr.com/eth', }, - [NETWORK.TESTNET]: { + ['testnet']: { address: '0x2890ba17efe978480615e330ecb65333b880928e', rpc: 'https://rpc.ankr.com/eth', // TODO: Put testnet info here }, + ['devnet']: { + address: '', + rpc: '', + }, }; -export const ALGORAND_INFO: { [key in NETWORK]: AlgorandInfo } = { - [NETWORK.MAINNET]: { +export const ALGORAND_INFO: { [key in Environment]: AlgorandInfo } = { + ['mainnet']: { appid: Number(CONTRACTS.MAINNET.algorand.core), algodToken: '', - algodServer: RPCS_BY_CHAIN[NETWORK.MAINNET].algorand - ? RPCS_BY_CHAIN[NETWORK.MAINNET].algorand + algodServer: RPCS_BY_CHAIN['mainnet'].algorand + ? (RPCS_BY_CHAIN['mainnet'].algorand as string) : '', algodPort: 443, server: 'https://mainnet-idx.algonode.cloud', port: 443, token: '', }, - [NETWORK.TESTNET]: { + ['testnet']: { appid: Number(CONTRACTS.TESTNET.algorand.core), algodToken: '', - algodServer: RPCS_BY_CHAIN[NETWORK.TESTNET].algorand - ? RPCS_BY_CHAIN[NETWORK.TESTNET].algorand + algodServer: RPCS_BY_CHAIN['testnet'].algorand + ? (RPCS_BY_CHAIN['testnet'].algorand as string) : '', algodPort: 443, - // TODO: Change to testnet info here; server: 'https://testnet-idx.algonode.cloud', port: 443, token: '', }, + ['devnet']: { + appid: 0, + algodToken: '', + algodServer: '', + algodPort: 0, + server: '', + port: 0, + token: '', + }, }; export const SEI_EXPLORER_GRAPHQL = 'https://pacific-1-graphql.alleslabs.dev/v1/graphql'; diff --git a/watcher/src/databases/__tests__/utils.test.ts b/watcher/src/databases/__tests__/utils.test.ts index a00d07e6..766e9e8b 100644 --- a/watcher/src/databases/__tests__/utils.test.ts +++ b/watcher/src/databases/__tests__/utils.test.ts @@ -1,9 +1,6 @@ import { CHAIN_ID_SOLANA } from '@certusone/wormhole-sdk/lib/cjs/utils/consts'; import { expect, test } from '@jest/globals'; -import { - INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN, - NETWORK, -} from '@wormhole-foundation/wormhole-monitor-common'; +import { INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN } from '@wormhole-foundation/wormhole-monitor-common'; import { JsonDatabase } from '../JsonDatabase'; import { getResumeBlockByChain, initDb, makeBlockKey } from '../utils'; @@ -14,13 +11,13 @@ test('getResumeBlockByChain', async () => { db.lastBlockByChain = { [CHAIN_ID_SOLANA]: blockKey }; // if a chain is in the database, that number should be returned expect(await db.getLastBlockByChain('solana')).toEqual(fauxBlock); - expect(await getResumeBlockByChain(NETWORK.MAINNET, 'solana')).toEqual(Number(fauxBlock) + 1); + expect(await getResumeBlockByChain('mainnet', 'solana')).toEqual(Number(fauxBlock) + 1); // if a chain is not in the database, the initial deployment block should be returned - expect(INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN[NETWORK.MAINNET].moonbeam).toBeDefined(); - expect(await getResumeBlockByChain(NETWORK.MAINNET, 'moonbeam')).toEqual( - Number(INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN[NETWORK.MAINNET].moonbeam) + expect(INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN['mainnet'].moonbeam).toBeDefined(); + expect(await getResumeBlockByChain('mainnet', 'moonbeam')).toEqual( + Number(INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN['mainnet'].moonbeam) ); // if neither, null should be returned - expect(INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN[NETWORK.MAINNET].unset).toBeUndefined(); - expect(await getResumeBlockByChain(NETWORK.MAINNET, 'unset')).toEqual(null); + expect(INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN['mainnet'].unset).toBeUndefined(); + expect(await getResumeBlockByChain('mainnet', 'unset')).toEqual(null); }); diff --git a/watcher/src/databases/utils.ts b/watcher/src/databases/utils.ts index 5cb7220f..6f3c8d95 100644 --- a/watcher/src/databases/utils.ts +++ b/watcher/src/databases/utils.ts @@ -1,8 +1,8 @@ import { ChainId, ChainName, coalesceChainId } from '@certusone/wormhole-sdk/lib/cjs/utils/consts'; import { + Environment, INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN, MAX_UINT_64, - NETWORK, padUint16, padUint64, } from '@wormhole-foundation/wormhole-monitor-common'; @@ -75,7 +75,7 @@ export const initDb = (startWatching: boolean = true): Database => { }; export const getResumeBlockByChain = async ( - network: NETWORK, + network: Environment, chain: ChainName ): Promise => { const lastBlock = await database.getLastBlockByChain(chain); diff --git a/watcher/src/index.ts b/watcher/src/index.ts index c8c3e0da..4b9f7d43 100644 --- a/watcher/src/index.ts +++ b/watcher/src/index.ts @@ -4,17 +4,16 @@ dotenv.config(); import { ChainName } from '@certusone/wormhole-sdk/lib/cjs/utils/consts'; import { initDb } from './databases/utils'; import { makeFinalizedWatcher } from './watchers/utils'; -import { getNetworkFromEnv } from './utils/environment'; -import { NETWORK } from '@wormhole-foundation/wormhole-monitor-common'; +import { Environment, getEnvironment } from '@wormhole-foundation/wormhole-monitor-common'; initDb(); -const network = getNetworkFromEnv(); +const network: Environment = getEnvironment(); // NOTE: supportedChains is in chainId order const supportedChains: ChainName[] = - network === NETWORK.TESTNET + network === 'testnet' ? [ // NOTE: The commented out chains are left in there to easily // identify which chains are not supported on testnet. diff --git a/watcher/src/utils/environment.ts b/watcher/src/utils/environment.ts index 61963196..ffc5e054 100644 --- a/watcher/src/utils/environment.ts +++ b/watcher/src/utils/environment.ts @@ -1,4 +1,7 @@ -import { NETWORK, assertEnvironmentVariable } from '@wormhole-foundation/wormhole-monitor-common'; +import { + Environment, + assertEnvironmentVariable, +} from '@wormhole-foundation/wormhole-monitor-common'; let loggingEnv: LoggingEnvironment | undefined = undefined; @@ -20,14 +23,3 @@ export const getEnvironment = () => { return loggingEnv; } }; - -export function getNetworkFromEnv(): NETWORK { - const networkEnv = assertEnvironmentVariable('NETWORK'); - if (networkEnv === 'mainnet') { - return NETWORK.MAINNET; - } - if (networkEnv === 'testnet') { - return NETWORK.TESTNET; - } - throw new Error(`Invalid network ${networkEnv}`); -} diff --git a/watcher/src/utils/near.ts b/watcher/src/utils/near.ts index c2b233b7..82916656 100644 --- a/watcher/src/utils/near.ts +++ b/watcher/src/utils/near.ts @@ -10,7 +10,7 @@ import { WormholePublishEventLog, } from '../types/near'; import { BlockId, BlockResult } from 'near-api-js/lib/providers/provider'; -import { NETWORK } from '@wormhole-foundation/wormhole-monitor-common'; +import { Environment } from '@wormhole-foundation/wormhole-monitor-common'; // The following is obtained by going to: https://explorer.near.org/accounts/contract.wormhole_crypto.near // and watching the network tab in the browser to see where the explorer is going. @@ -18,15 +18,9 @@ const NEAR_EXPLORER_TRANSACTION_URL = 'https://explorer-backend-mainnet-prod-24ktefolwq-uc.a.run.app/trpc/transaction.listByAccountId'; export const NEAR_ARCHIVE_RPC = 'https://archival-rpc.mainnet.near.org'; -export const getNearProvider = async (network: NETWORK, rpc: string): Promise => { +export const getNearProvider = async (network: Environment, rpc: string): Promise => { let connection; - if (network === NETWORK.MAINNET) { - connection = await connect({ nodeUrl: rpc, networkId: 'mainnet' }); - } else if (network === NETWORK.TESTNET) { - connection = await connect({ nodeUrl: rpc, networkId: 'testnet' }); - } else { - throw new Error(`Invalid network ${network}`); - } + connection = await connect({ nodeUrl: rpc, networkId: network }); const provider = connection.connection.provider; return provider; }; diff --git a/watcher/src/watchers/AlgorandWatcher.ts b/watcher/src/watchers/AlgorandWatcher.ts index 8509986b..af20a8f6 100644 --- a/watcher/src/watchers/AlgorandWatcher.ts +++ b/watcher/src/watchers/AlgorandWatcher.ts @@ -3,7 +3,7 @@ import { Watcher } from './Watcher'; import { ALGORAND_INFO } from '../consts'; import { VaasByBlock } from '../databases/types'; import { makeBlockKey, makeVaaKey } from '../databases/utils'; -import { NETWORK } from '@wormhole-foundation/wormhole-monitor-common'; +import { Environment } from '@wormhole-foundation/wormhole-monitor-common'; type Message = { blockKey: string; @@ -17,7 +17,7 @@ export class AlgorandWatcher extends Watcher { algodClient: algosdk.Algodv2; indexerClient: algosdk.Indexer; - constructor(network: NETWORK) { + constructor(network: Environment) { super(network, 'algorand'); if (!ALGORAND_INFO[this.network].algodServer) { diff --git a/watcher/src/watchers/AptosWatcher.ts b/watcher/src/watchers/AptosWatcher.ts index 7e1fcdfc..a4ac8883 100644 --- a/watcher/src/watchers/AptosWatcher.ts +++ b/watcher/src/watchers/AptosWatcher.ts @@ -1,7 +1,7 @@ import { CONTRACTS } from '@certusone/wormhole-sdk/lib/cjs/utils'; import { + Environment, INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN, - NETWORK, } from '@wormhole-foundation/wormhole-monitor-common'; import { AptosClient } from 'aptos'; import { z } from 'zod'; @@ -23,11 +23,11 @@ export class AptosWatcher extends Watcher { coreBridgeAddress: string; eventHandle: string; - constructor(network: NETWORK) { + constructor(network: Environment) { super(network, 'aptos'); this.client = new AptosClient(RPCS_BY_CHAIN[this.network][this.chain]!); this.coreBridgeAddress = - network === NETWORK.MAINNET ? CONTRACTS.MAINNET.aptos.core : CONTRACTS.TESTNET.aptos.core; + network === 'mainnet' ? CONTRACTS.MAINNET.aptos.core : CONTRACTS.TESTNET.aptos.core; this.eventHandle = `${this.coreBridgeAddress}::state::WormholeMessageHandle`; } diff --git a/watcher/src/watchers/ArbitrumWatcher.ts b/watcher/src/watchers/ArbitrumWatcher.ts index 46e56b3e..693a780f 100644 --- a/watcher/src/watchers/ArbitrumWatcher.ts +++ b/watcher/src/watchers/ArbitrumWatcher.ts @@ -1,7 +1,7 @@ import axios from 'axios'; import { AXIOS_CONFIG_JSON, RPCS_BY_CHAIN } from '../consts'; import { EVMWatcher } from './EVMWatcher'; -import { NETWORK } from '@wormhole-foundation/wormhole-monitor-common'; +import { Environment } from '@wormhole-foundation/wormhole-monitor-common'; export class ArbitrumWatcher extends EVMWatcher { rpc: string | undefined; @@ -10,7 +10,7 @@ export class ArbitrumWatcher extends EVMWatcher { l1L2Map: Map; lastEthTime: number; - constructor(network: NETWORK) { + constructor(network: Environment) { super(network, 'arbitrum'); this.rpc = RPCS_BY_CHAIN[this.network][this.chain]; diff --git a/watcher/src/watchers/BSCWatcher.ts b/watcher/src/watchers/BSCWatcher.ts index cc020e13..9c246346 100644 --- a/watcher/src/watchers/BSCWatcher.ts +++ b/watcher/src/watchers/BSCWatcher.ts @@ -1,8 +1,8 @@ -import { NETWORK } from '@wormhole-foundation/wormhole-monitor-common'; +import { Environment } from '@wormhole-foundation/wormhole-monitor-common'; import { EVMWatcher } from './EVMWatcher'; export class BSCWatcher extends EVMWatcher { - constructor(network: NETWORK) { + constructor(network: Environment) { super(network, 'bsc'); } async getFinalizedBlockNumber(): Promise { diff --git a/watcher/src/watchers/CosmwasmWatcher.ts b/watcher/src/watchers/CosmwasmWatcher.ts index 961819e0..f107c263 100644 --- a/watcher/src/watchers/CosmwasmWatcher.ts +++ b/watcher/src/watchers/CosmwasmWatcher.ts @@ -7,7 +7,7 @@ import { Watcher } from './Watcher'; import { SHA256 } from 'jscrypto/SHA256'; import { Base64 } from 'jscrypto/Base64'; import { isBase64Encoded } from '../utils/isBase64Encoded'; -import { NETWORK } from '@wormhole-foundation/wormhole-monitor-common'; +import { Environment } from '@wormhole-foundation/wormhole-monitor-common'; export class CosmwasmWatcher extends Watcher { latestBlockTag: string; @@ -16,7 +16,7 @@ export class CosmwasmWatcher extends Watcher { rpc: string | undefined; latestBlockHeight: number; - constructor(network: NETWORK, chain: CosmWasmChainName | 'wormchain') { + constructor(network: Environment, chain: CosmWasmChainName | 'wormchain') { super(network, chain); if (chain === 'injective') { throw new Error('Please use InjectiveExplorerWatcher for injective'); diff --git a/watcher/src/watchers/EVMWatcher.ts b/watcher/src/watchers/EVMWatcher.ts index d194d354..fef72377 100644 --- a/watcher/src/watchers/EVMWatcher.ts +++ b/watcher/src/watchers/EVMWatcher.ts @@ -7,7 +7,7 @@ import { AXIOS_CONFIG_JSON, RPCS_BY_CHAIN } from '../consts'; import { VaasByBlock } from '../databases/types'; import { makeBlockKey, makeVaaKey } from '../databases/utils'; import { Watcher } from './Watcher'; -import { NETWORK } from '@wormhole-foundation/wormhole-monitor-common'; +import { Environment } from '@wormhole-foundation/wormhole-monitor-common'; // This is the hash for topic[0] of the core contract event LogMessagePublished // https://github.com/wormhole-foundation/wormhole/blob/main/ethereum/contracts/Implementation.sol#L12 @@ -31,7 +31,7 @@ export class EVMWatcher extends Watcher { lastTimestamp: number; latestFinalizedBlockNumber: number; - constructor(network: NETWORK, chain: EVMChainName, finalizedBlockTag: BlockTag = 'latest') { + constructor(network: Environment, chain: EVMChainName, finalizedBlockTag: BlockTag = 'latest') { super(network, chain); this.lastTimestamp = 0; this.latestFinalizedBlockNumber = 0; diff --git a/watcher/src/watchers/InjectiveExplorerWatcher.ts b/watcher/src/watchers/InjectiveExplorerWatcher.ts index e8d452e0..f5c36b59 100644 --- a/watcher/src/watchers/InjectiveExplorerWatcher.ts +++ b/watcher/src/watchers/InjectiveExplorerWatcher.ts @@ -5,7 +5,7 @@ import { VaasByBlock } from '../databases/types'; import { makeBlockKey, makeVaaKey } from '../databases/utils'; import { EventObjectsTypes, RawLogEvents } from './TerraExplorerWatcher'; import { Watcher } from './Watcher'; -import { NETWORK } from '@wormhole-foundation/wormhole-monitor-common'; +import { Environment } from '@wormhole-foundation/wormhole-monitor-common'; export class InjectiveExplorerWatcher extends Watcher { // Arbitrarily large since the code here is capable of pulling all logs from all via indexer pagination @@ -18,7 +18,7 @@ export class InjectiveExplorerWatcher extends Watcher { rpc: string | undefined; latestBlockHeight: number; - constructor(network: NETWORK) { + constructor(network: Environment) { super(network, 'injective'); this.rpc = RPCS_BY_CHAIN[this.network][this.chain]; if (!this.rpc) { diff --git a/watcher/src/watchers/MoonbeamWatcher.ts b/watcher/src/watchers/MoonbeamWatcher.ts index de9fb976..8a29579a 100644 --- a/watcher/src/watchers/MoonbeamWatcher.ts +++ b/watcher/src/watchers/MoonbeamWatcher.ts @@ -1,10 +1,10 @@ -import { NETWORK, sleep } from '@wormhole-foundation/wormhole-monitor-common'; +import { Environment, sleep } from '@wormhole-foundation/wormhole-monitor-common'; import axios from 'axios'; import { AXIOS_CONFIG_JSON, RPCS_BY_CHAIN } from '../consts'; import { EVMWatcher } from './EVMWatcher'; export class MoonbeamWatcher extends EVMWatcher { - constructor(network: NETWORK) { + constructor(network: Environment) { super(network, 'moonbeam'); } async getFinalizedBlockNumber(): Promise { diff --git a/watcher/src/watchers/NearArchiveWatcher.ts b/watcher/src/watchers/NearArchiveWatcher.ts index da8c1a33..a19dfc90 100644 --- a/watcher/src/watchers/NearArchiveWatcher.ts +++ b/watcher/src/watchers/NearArchiveWatcher.ts @@ -15,12 +15,15 @@ import { isWormholePublishEventLog, } from '../utils/near'; import { Watcher } from './Watcher'; -import { NETWORK, assertEnvironmentVariable } from '@wormhole-foundation/wormhole-monitor-common'; +import { + Environment, + assertEnvironmentVariable, +} from '@wormhole-foundation/wormhole-monitor-common'; export class NearArchiveWatcher extends Watcher { provider: Provider | null = null; - constructor(network: NETWORK) { + constructor(network: Environment) { super(network, 'near'); } diff --git a/watcher/src/watchers/NearWatcher.ts b/watcher/src/watchers/NearWatcher.ts index b302f214..86c0c355 100644 --- a/watcher/src/watchers/NearWatcher.ts +++ b/watcher/src/watchers/NearWatcher.ts @@ -10,12 +10,12 @@ import { makeBlockKey, makeVaaKey } from '../databases/utils'; import { EventLog } from '../types/near'; import { getNearProvider, isWormholePublishEventLog } from '../utils/near'; import { Watcher } from './Watcher'; -import { NETWORK } from '@wormhole-foundation/wormhole-monitor-common'; +import { Environment } from '@wormhole-foundation/wormhole-monitor-common'; export class NearWatcher extends Watcher { provider: Provider | null = null; - constructor(network: NETWORK) { + constructor(network: Environment) { super(network, 'near'); } diff --git a/watcher/src/watchers/PolygonWatcher.ts b/watcher/src/watchers/PolygonWatcher.ts index dbd3846e..7d36f506 100644 --- a/watcher/src/watchers/PolygonWatcher.ts +++ b/watcher/src/watchers/PolygonWatcher.ts @@ -2,10 +2,10 @@ import axios from 'axios'; import { ethers } from 'ethers'; import { AXIOS_CONFIG_JSON, POLYGON_ROOT_CHAIN_INFO } from '../consts'; import { EVMWatcher } from './EVMWatcher'; -import { NETWORK } from '@wormhole-foundation/wormhole-monitor-common'; +import { Environment } from '@wormhole-foundation/wormhole-monitor-common'; export class PolygonWatcher extends EVMWatcher { - constructor(network: NETWORK) { + constructor(network: Environment) { super(network, 'polygon'); } async getFinalizedBlockNumber(): Promise { diff --git a/watcher/src/watchers/SeiExplorerWatcher.ts b/watcher/src/watchers/SeiExplorerWatcher.ts index e1406bbb..54b02605 100644 --- a/watcher/src/watchers/SeiExplorerWatcher.ts +++ b/watcher/src/watchers/SeiExplorerWatcher.ts @@ -4,7 +4,7 @@ import { AXIOS_CONFIG_JSON, SEI_EXPLORER_GRAPHQL, SEI_EXPLORER_TXS } from '../co import { VaasByBlock } from '../databases/types'; import { makeBlockKey, makeVaaKey } from '../databases/utils'; import { CosmwasmHashResult, CosmwasmWatcher } from './CosmwasmWatcher'; -import { NETWORK, sleep } from '@wormhole-foundation/wormhole-monitor-common'; +import { Environment, sleep } from '@wormhole-foundation/wormhole-monitor-common'; type SeiExplorerAccountTransactionsResponse = { data: { @@ -29,7 +29,7 @@ type SeiExplorerAccountTransactionsResponse = { }; export class SeiExplorerWatcher extends CosmwasmWatcher { - constructor(network: NETWORK) { + constructor(network: Environment) { super(network, 'sei'); // arbitrarily large since the code here is capable of pulling all logs from all via indexer pagination this.maximumBatchSize = 1_000_000; diff --git a/watcher/src/watchers/SolanaWatcher.ts b/watcher/src/watchers/SolanaWatcher.ts index 4ddcbf2a..f60663b1 100644 --- a/watcher/src/watchers/SolanaWatcher.ts +++ b/watcher/src/watchers/SolanaWatcher.ts @@ -15,7 +15,7 @@ import { VaasByBlock } from '../databases/types'; import { makeBlockKey, makeVaaKey } from '../databases/utils'; import { isLegacyMessage, normalizeCompileInstruction } from '../utils/solana'; import { Watcher } from './Watcher'; -import { NETWORK } from '@wormhole-foundation/wormhole-monitor-common'; +import { Environment } from '@wormhole-foundation/wormhole-monitor-common'; const WORMHOLE_PROGRAM_ID = CONTRACTS.MAINNET.solana.core; const COMMITMENT: Commitment = 'finalized'; @@ -35,7 +35,7 @@ export class SolanaWatcher extends Watcher { connection: Connection | undefined; - constructor(network: NETWORK) { + constructor(network: Environment) { super(network, 'solana'); this.rpc = RPCS_BY_CHAIN[this.network].solana!; this.programId = WORMHOLE_PROGRAM_ID; diff --git a/watcher/src/watchers/SuiWatcher.ts b/watcher/src/watchers/SuiWatcher.ts index 4b0ff374..8a560c09 100644 --- a/watcher/src/watchers/SuiWatcher.ts +++ b/watcher/src/watchers/SuiWatcher.ts @@ -10,7 +10,7 @@ import { RPCS_BY_CHAIN } from '../consts'; import { VaasByBlock } from '../databases/types'; import { Watcher } from './Watcher'; import { makeBlockKey, makeVaaKey } from '../databases/utils'; -import { NETWORK } from '@wormhole-foundation/wormhole-monitor-common'; +import { Environment } from '@wormhole-foundation/wormhole-monitor-common'; const SUI_EVENT_HANDLE = `0x5306f64e312b581766351c07af79c72fcb1cd25147157fdc2f8ad76de9a3fb6a::publish_message::WormholeMessage`; @@ -27,7 +27,7 @@ export class SuiWatcher extends Watcher { client: JsonRpcClient; maximumBatchSize: number = 100000; // arbitrarily large as this pages back by events - constructor(network: NETWORK) { + constructor(network: Environment) { super(network, 'sui'); this.client = new JsonRpcClient(RPCS_BY_CHAIN[this.network][this.chain]!); } diff --git a/watcher/src/watchers/TerraExplorerWatcher.ts b/watcher/src/watchers/TerraExplorerWatcher.ts index 97a4fbad..dfebf8af 100644 --- a/watcher/src/watchers/TerraExplorerWatcher.ts +++ b/watcher/src/watchers/TerraExplorerWatcher.ts @@ -4,7 +4,7 @@ import { AXIOS_CONFIG_JSON, RPCS_BY_CHAIN } from '../consts'; import { VaasByBlock } from '../databases/types'; import { makeBlockKey, makeVaaKey } from '../databases/utils'; import { Watcher } from './Watcher'; -import { NETWORK } from '@wormhole-foundation/wormhole-monitor-common'; +import { Environment } from '@wormhole-foundation/wormhole-monitor-common'; export class TerraExplorerWatcher extends Watcher { // Arbitrarily large since the code here is capable of pulling all logs from all via indexer pagination @@ -16,7 +16,7 @@ export class TerraExplorerWatcher extends Watcher { rpc: string | undefined; latestBlockHeight: number; - constructor(network: NETWORK, chain: CosmWasmChainName) { + constructor(network: Environment, chain: CosmWasmChainName) { super(network, chain); this.rpc = RPCS_BY_CHAIN[this.network][this.chain]; if (!this.rpc) { diff --git a/watcher/src/watchers/Watcher.ts b/watcher/src/watchers/Watcher.ts index f1a36e5e..4b83cae8 100644 --- a/watcher/src/watchers/Watcher.ts +++ b/watcher/src/watchers/Watcher.ts @@ -1,7 +1,7 @@ import { ChainName } from '@certusone/wormhole-sdk/lib/cjs/utils/consts'; import { + Environment, INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN, - NETWORK, sleep, } from '@wormhole-foundation/wormhole-monitor-common'; import { z } from 'zod'; @@ -12,11 +12,11 @@ import { getLogger, WormholeLogger } from '../utils/logger'; export class Watcher { chain: ChainName; - network: NETWORK; + network: Environment; logger: WormholeLogger; maximumBatchSize: number = 100; - constructor(network: NETWORK, chain: ChainName) { + constructor(network: Environment, chain: ChainName) { this.network = network; this.chain = chain; this.logger = getLogger(chain); diff --git a/watcher/src/watchers/WormchainWatcher.ts b/watcher/src/watchers/WormchainWatcher.ts index 67491546..1fe3e18e 100644 --- a/watcher/src/watchers/WormchainWatcher.ts +++ b/watcher/src/watchers/WormchainWatcher.ts @@ -4,7 +4,7 @@ import { AXIOS_CONFIG_JSON, RPCS_BY_CHAIN } from '../consts'; import { VaasByBlock } from '../databases/types'; import { makeBlockKey, makeVaaKey } from '../databases/utils'; import { CosmwasmBlockResult, CosmwasmWatcher } from './CosmwasmWatcher'; -import { NETWORK } from '@wormhole-foundation/wormhole-monitor-common'; +import { Environment } from '@wormhole-foundation/wormhole-monitor-common'; export class WormchainWatcher extends CosmwasmWatcher { latestBlockTag: string; @@ -13,7 +13,7 @@ export class WormchainWatcher extends CosmwasmWatcher { rpc: string | undefined; latestBlockHeight: number; - constructor(network: NETWORK) { + constructor(network: Environment) { super(network, 'wormchain'); this.rpc = RPCS_BY_CHAIN[this.network][this.chain]; if (!this.rpc) { diff --git a/watcher/src/watchers/__tests__/AlgorandWatcher.test.ts b/watcher/src/watchers/__tests__/AlgorandWatcher.test.ts index 7365b792..544cfc6b 100644 --- a/watcher/src/watchers/__tests__/AlgorandWatcher.test.ts +++ b/watcher/src/watchers/__tests__/AlgorandWatcher.test.ts @@ -1,30 +1,27 @@ import { expect, jest, test } from '@jest/globals'; -import { - INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN, - NETWORK, -} from '@wormhole-foundation/wormhole-monitor-common'; +import { INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN } from '@wormhole-foundation/wormhole-monitor-common'; import { AlgorandWatcher } from '../AlgorandWatcher'; jest.setTimeout(180000); const initialAlgorandBlock = Number( - INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN[NETWORK.MAINNET].algorand + INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN['mainnet'].algorand ); test('getFinalizedBlockNumber', async () => { - const watcher = new AlgorandWatcher(NETWORK.MAINNET); + const watcher = new AlgorandWatcher('mainnet'); const blockNumber = await watcher.getFinalizedBlockNumber(); expect(blockNumber).toBeGreaterThan(initialAlgorandBlock); }); test('getMessagesForBlocks', async () => { - const watcher = new AlgorandWatcher(NETWORK.MAINNET); + const watcher = new AlgorandWatcher('mainnet'); const messages = await watcher.getMessagesForBlocks(25692450, 25692450); expect(messages).toMatchObject({ '25692450/2022-12-21T02:00:40.000Z': [] }); }); test('getMessagesForBlocks initial block', async () => { - const watcher = new AlgorandWatcher(NETWORK.MAINNET); + const watcher = new AlgorandWatcher('mainnet'); const messages = await watcher.getMessagesForBlocks(initialAlgorandBlock, initialAlgorandBlock); expect(messages).toMatchObject({ '22931277/2022-08-19T15:10:48.000Z': [ @@ -34,13 +31,13 @@ test('getMessagesForBlocks initial block', async () => { }); test('getMessagesForBlocks indexer pagination support', async () => { - const watcher = new AlgorandWatcher(NETWORK.MAINNET); + const watcher = new AlgorandWatcher('mainnet'); const messages = await watcher.getMessagesForBlocks(initialAlgorandBlock, 27069946); expect(Object.keys(messages).length).toEqual(420); }); test('getMessagesForBlocks seq < 192', async () => { - const watcher = new AlgorandWatcher(NETWORK.MAINNET); + const watcher = new AlgorandWatcher('mainnet'); const messages = await watcher.getMessagesForBlocks(25428873, 25428873); expect(messages).toMatchObject({ '25428873/2022-12-09T18:10:08.000Z': [ @@ -50,7 +47,7 @@ test('getMessagesForBlocks seq < 192', async () => { }); test('getMessagesForBlocks seq = 192', async () => { - const watcher = new AlgorandWatcher(NETWORK.MAINNET); + const watcher = new AlgorandWatcher('mainnet'); const messages = await watcher.getMessagesForBlocks(25433218, 25433218); expect(messages).toMatchObject({ '25433218/2022-12-09T22:40:55.000Z': [ @@ -60,7 +57,7 @@ test('getMessagesForBlocks seq = 192', async () => { }); test('getMessagesForBlocks seq > 383', async () => { - const watcher = new AlgorandWatcher(NETWORK.MAINNET); + const watcher = new AlgorandWatcher('mainnet'); const messages = await watcher.getMessagesForBlocks(26856742, 26856742); expect(messages).toMatchObject({ '26856742/2023-02-09T09:05:04.000Z': [ @@ -70,7 +67,7 @@ test('getMessagesForBlocks seq > 383', async () => { }); test('getMessagesForBlocks on known empty block', async () => { - const watcher = new AlgorandWatcher(NETWORK.MAINNET); + const watcher = new AlgorandWatcher('mainnet'); const messages = await watcher.getMessagesForBlocks(23761195, 23761195); expect(messages).toMatchObject({ '23761195/2022-09-28T21:42:30.000Z': [] }); }); diff --git a/watcher/src/watchers/__tests__/AptosWatcher.test.ts b/watcher/src/watchers/__tests__/AptosWatcher.test.ts index 14921c22..57096d3a 100644 --- a/watcher/src/watchers/__tests__/AptosWatcher.test.ts +++ b/watcher/src/watchers/__tests__/AptosWatcher.test.ts @@ -1,24 +1,21 @@ import { expect, jest, test } from '@jest/globals'; -import { - INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN, - NETWORK, -} from '@wormhole-foundation/wormhole-monitor-common/dist/consts'; +import { INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN } from '@wormhole-foundation/wormhole-monitor-common/dist/consts'; import { AptosWatcher } from '../AptosWatcher'; jest.setTimeout(60000); const INITAL_SEQUENCE_NUMBER = Number( - INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN[NETWORK.MAINNET].aptos ?? 0 + INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN['mainnet'].aptos ?? 0 ); test('getFinalizedSequenceNumber', async () => { - const watcher = new AptosWatcher(NETWORK.MAINNET); + const watcher = new AptosWatcher('mainnet'); const blockNumber = await watcher.getFinalizedBlockNumber(); expect(blockNumber).toBeGreaterThan(INITAL_SEQUENCE_NUMBER); }); test('getMessagesForSequenceNumbers', async () => { - const watcher = new AptosWatcher(NETWORK.MAINNET); + const watcher = new AptosWatcher('mainnet'); const messages = await watcher.getMessagesForBlocks(0, 1); expect(messages).toMatchObject({ '1095891/2022-10-19T00:55:54.676Z/0': [ diff --git a/watcher/src/watchers/__tests__/ArbitrumWatcher.test.ts b/watcher/src/watchers/__tests__/ArbitrumWatcher.test.ts index 37567e60..43f8502d 100644 --- a/watcher/src/watchers/__tests__/ArbitrumWatcher.test.ts +++ b/watcher/src/watchers/__tests__/ArbitrumWatcher.test.ts @@ -1,21 +1,16 @@ import { expect, jest, test } from '@jest/globals'; -import { - INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN, - NETWORK, -} from '@wormhole-foundation/wormhole-monitor-common'; +import { INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN } from '@wormhole-foundation/wormhole-monitor-common'; import { ArbitrumWatcher } from '../ArbitrumWatcher'; jest.setTimeout(60000); const initialArbitrumBlock = Number( - INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN[NETWORK.MAINNET].arbitrum -); -const initialEthBlock = Number( - INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN[NETWORK.MAINNET].ethereum + INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN['mainnet'].arbitrum ); +const initialEthBlock = Number(INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN['mainnet'].ethereum); test('getFinalizedBlockNumber', async () => { - const watcher = new ArbitrumWatcher(NETWORK.MAINNET); + const watcher = new ArbitrumWatcher('mainnet'); const blockNumber = await watcher.getFinalizedBlockNumber(); // The blockNumber is 0 because the most recent L2 block isn't in // a finalized L1 block, yet. It's in an L1 block. That L1 block @@ -28,7 +23,7 @@ test('getFinalizedBlockNumber', async () => { }); test('getMessagesForBlocks', async () => { - const watcher = new ArbitrumWatcher(NETWORK.MAINNET); + const watcher = new ArbitrumWatcher('mainnet'); const vaasByBlock = await watcher.getMessagesForBlocks(114500582, 114500584); const entries = Object.entries(vaasByBlock); expect(entries.length).toEqual(3); diff --git a/watcher/src/watchers/__tests__/BaseWatcher.test.ts b/watcher/src/watchers/__tests__/BaseWatcher.test.ts index 2b14168f..5f563f0f 100644 --- a/watcher/src/watchers/__tests__/BaseWatcher.test.ts +++ b/watcher/src/watchers/__tests__/BaseWatcher.test.ts @@ -1,26 +1,21 @@ import { expect, jest, test } from '@jest/globals'; -import { - INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN, - NETWORK, -} from '@wormhole-foundation/wormhole-monitor-common'; +import { INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN } from '@wormhole-foundation/wormhole-monitor-common'; import { EVMWatcher } from '../EVMWatcher'; import { NEAR_ARCHIVE_RPC } from '../../utils/near'; jest.setTimeout(60000); -const initialBaseBlock = Number( - INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN[NETWORK.MAINNET].base -); +const initialBaseBlock = Number(INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN['mainnet'].base); test('getFinalizedBlockNumber', async () => { - const watcher = new EVMWatcher(NETWORK.MAINNET, 'base'); + const watcher = new EVMWatcher('mainnet', 'base'); const blockNumber = await watcher.getFinalizedBlockNumber(); console.log('blockNumber', blockNumber); expect(blockNumber).toBeGreaterThan(initialBaseBlock); }); test('getMessagesForBlocks', async () => { - const watcher = new EVMWatcher(NETWORK.MAINNET, 'base'); + const watcher = new EVMWatcher('mainnet', 'base'); const vaasByBlock = await watcher.getMessagesForBlocks(1544175, 1544185); expect(vaasByBlock).toMatchObject({ '1544175/2023-07-20T18:28:17.000Z': [], @@ -38,7 +33,7 @@ test('getMessagesForBlocks', async () => { }); test('getMessagesForBlockWithWHMsg', async () => { - const watcher = new EVMWatcher(NETWORK.MAINNET, 'base'); + const watcher = new EVMWatcher('mainnet', 'base'); const vaasByBlock = await watcher.getMessagesForBlocks(1557420, 1557429); expect(vaasByBlock).toMatchObject({ '1557420/2023-07-21T01:49:47.000Z': [], diff --git a/watcher/src/watchers/__tests__/CosmwasmWatcher.test.ts b/watcher/src/watchers/__tests__/CosmwasmWatcher.test.ts index 7f73b505..f6b5da70 100644 --- a/watcher/src/watchers/__tests__/CosmwasmWatcher.test.ts +++ b/watcher/src/watchers/__tests__/CosmwasmWatcher.test.ts @@ -4,22 +4,19 @@ import { TerraExplorerWatcher } from '../TerraExplorerWatcher'; import { InjectiveExplorerWatcher } from '../InjectiveExplorerWatcher'; import { SeiExplorerWatcher } from '../SeiExplorerWatcher'; import { WormchainWatcher } from '../WormchainWatcher'; -import { - INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN, - NETWORK, -} from '@wormhole-foundation/wormhole-monitor-common'; +import { INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN } from '@wormhole-foundation/wormhole-monitor-common'; import { isBase64Encoded } from '../../utils/isBase64Encoded'; jest.setTimeout(60000); test('getFinalizedBlockNumber(terra2)', async () => { - const watcher = new CosmwasmWatcher(NETWORK.MAINNET, 'terra2'); + const watcher = new CosmwasmWatcher('mainnet', 'terra2'); const blockNumber = await watcher.getFinalizedBlockNumber(); expect(blockNumber).toBeGreaterThan(3181746); }); test('getMessagesForBlocks(terra2)', async () => { - const watcher = new CosmwasmWatcher(NETWORK.MAINNET, 'terra2'); + const watcher = new CosmwasmWatcher('mainnet', 'terra2'); const vaasByBlock = await watcher.getMessagesForBlocks(3165191, 3165192); const entries = Object.entries(vaasByBlock); expect(entries.length).toEqual(2); @@ -34,7 +31,7 @@ test('getMessagesForBlocks(terra2)', async () => { }); test('getMessagesForBlocks(terra2)', async () => { - const watcher = new CosmwasmWatcher(NETWORK.MAINNET, 'terra2'); + const watcher = new CosmwasmWatcher('mainnet', 'terra2'); const vaasByBlock = await watcher.getMessagesForBlocks(5635710, 5635712); const entries = Object.entries(vaasByBlock); console.log(entries); @@ -48,14 +45,14 @@ test('getMessagesForBlocks(terra2)', async () => { }); test.skip('getFinalizedBlockNumber(terra)', async () => { - const watcher = new CosmwasmWatcher(NETWORK.MAINNET, 'terra'); + const watcher = new CosmwasmWatcher('mainnet', 'terra'); const blockNumber = await watcher.getFinalizedBlockNumber(); expect(blockNumber).toBeGreaterThan(10980872); }); // flaky rpc, skip test.skip('getMessagesForBlocks(terra)', async () => { - const watcher = new CosmwasmWatcher(NETWORK.MAINNET, 'terra'); + const watcher = new CosmwasmWatcher('mainnet', 'terra'); const vaasByBlock = await watcher.getMessagesForBlocks(10974196, 10974197); const entries = Object.entries(vaasByBlock); expect(entries.length).toEqual(2); @@ -70,14 +67,14 @@ test.skip('getMessagesForBlocks(terra)', async () => { }); test('getFinalizedBlockNumber(terra explorer)', async () => { - const watcher = new TerraExplorerWatcher(NETWORK.MAINNET, 'terra'); + const watcher = new TerraExplorerWatcher('mainnet', 'terra'); const blockNumber = await watcher.getFinalizedBlockNumber(); expect(blockNumber).toBeGreaterThan(10980872); }); // flaky rpc, skip test('getMessagesForBlocks(terra explorer)', async () => { - const watcher = new TerraExplorerWatcher(NETWORK.MAINNET, 'terra'); + const watcher = new TerraExplorerWatcher('mainnet', 'terra'); const vaasByBlock = await watcher.getMessagesForBlocks(14506733, 14506740); const entries = Object.entries(vaasByBlock); expect(entries.length).toEqual(2); @@ -93,7 +90,7 @@ test('getMessagesForBlocks(terra explorer)', async () => { // flaky rpc, skip test.skip('getMessagesForBlocks(terra explorer, no useful info)', async () => { - const watcher = new TerraExplorerWatcher(NETWORK.MAINNET, 'terra'); + const watcher = new TerraExplorerWatcher('mainnet', 'terra'); const vaasByBlock = await watcher.getMessagesForBlocks(10975000, 10975010); const entries = Object.entries(vaasByBlock); expect(entries.length).toEqual(1); @@ -103,13 +100,13 @@ test.skip('getMessagesForBlocks(terra explorer, no useful info)', async () => { }); test('getFinalizedBlockNumber(xpla)', async () => { - const watcher = new CosmwasmWatcher(NETWORK.MAINNET, 'xpla'); + const watcher = new CosmwasmWatcher('mainnet', 'xpla'); const blockNumber = await watcher.getFinalizedBlockNumber(); expect(blockNumber).toBeGreaterThan(1980633); }); test('getMessagesForBlocks(xpla)', async () => { - const watcher = new CosmwasmWatcher(NETWORK.MAINNET, 'xpla'); + const watcher = new CosmwasmWatcher('mainnet', 'xpla'); const vaasByBlock = await watcher.getMessagesForBlocks(1645812, 1645813); const entries = Object.entries(vaasByBlock); expect(entries.length).toEqual(2); @@ -124,13 +121,13 @@ test('getMessagesForBlocks(xpla)', async () => { }); test('getFinalizedBlockNumber(injective)', async () => { - const watcher = new InjectiveExplorerWatcher(NETWORK.MAINNET); + const watcher = new InjectiveExplorerWatcher('mainnet'); const blockNumber = await watcher.getFinalizedBlockNumber(); expect(blockNumber).toBeGreaterThan(23333696); }); test('getMessagesForBlocks(injective)', async () => { - const watcher = new InjectiveExplorerWatcher(NETWORK.MAINNET); + const watcher = new InjectiveExplorerWatcher('mainnet'); const vaasByBlock = await watcher.getMessagesForBlocks(56405501, 56405502); // const vaasByBlock = await watcher.getMessagesForBlocks(4209642, 4209643); // Testnet const entries = Object.entries(vaasByBlock); @@ -147,7 +144,7 @@ test('getMessagesForBlocks(injective)', async () => { // skipped because the SeiExplorerWatcher is used test.skip('getFinalizedBlockNumber(sei)', async () => { - const watcher = new CosmwasmWatcher(NETWORK.MAINNET, 'sei'); + const watcher = new CosmwasmWatcher('mainnet', 'sei'); const blockNumber = await watcher.getFinalizedBlockNumber(); console.log(blockNumber); expect(blockNumber).toBeGreaterThan(0); @@ -155,7 +152,7 @@ test.skip('getFinalizedBlockNumber(sei)', async () => { // skipped because the SeiExplorerWatcher is used test.skip('getMessagesForBlocks(sei)', async () => { - const watcher = new CosmwasmWatcher(NETWORK.MAINNET, 'sei'); + const watcher = new CosmwasmWatcher('mainnet', 'sei'); const vaasByBlock = await watcher.getMessagesForBlocks(18907686, 18907687); const entries = Object.entries(vaasByBlock); console.log(entries); @@ -172,7 +169,7 @@ test.skip('getMessagesForBlocks(sei)', async () => { }); test('getFinalizedBlockNumber(sei explorer)', async () => { - const watcher = new SeiExplorerWatcher(NETWORK.MAINNET); + const watcher = new SeiExplorerWatcher('mainnet'); const blockNumber = await watcher.getFinalizedBlockNumber(); console.log(blockNumber); expect(blockNumber).toBeGreaterThan(0); @@ -180,7 +177,7 @@ test('getFinalizedBlockNumber(sei explorer)', async () => { // skipped because it takes more and more time to paginate back test.skip('getMessagesForBlocks(sei explorer)', async () => { - const watcher = new SeiExplorerWatcher(NETWORK.MAINNET); + const watcher = new SeiExplorerWatcher('mainnet'); const vaasByBlock = await watcher.getMessagesForBlocks(19061244, 19061245); const entries = Object.entries(vaasByBlock); console.log(entries); @@ -196,16 +193,16 @@ test.skip('getMessagesForBlocks(sei explorer)', async () => { }); test('getFinalizedBlockNumber(wormchain)', async () => { - const watcher = new WormchainWatcher(NETWORK.MAINNET); + const watcher = new WormchainWatcher('mainnet'); const blockNumber = await watcher.getFinalizedBlockNumber(); console.log(blockNumber); expect(blockNumber).toBeGreaterThan( - Number(INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN[NETWORK.MAINNET].wormchain) + Number(INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN['mainnet'].wormchain) ); }); test('getMessagesForBlocks(wormchain)', async () => { - const watcher = new WormchainWatcher(NETWORK.MAINNET); + const watcher = new WormchainWatcher('mainnet'); const vaasByBlock = await watcher.getMessagesForBlocks(4510119, 4510119); const entries = Object.entries(vaasByBlock); console.log(entries); diff --git a/watcher/src/watchers/__tests__/EVMWatcher.test.ts b/watcher/src/watchers/__tests__/EVMWatcher.test.ts index 8d0cfe30..1990d832 100644 --- a/watcher/src/watchers/__tests__/EVMWatcher.test.ts +++ b/watcher/src/watchers/__tests__/EVMWatcher.test.ts @@ -1,28 +1,19 @@ import { CONTRACTS } from '@certusone/wormhole-sdk/lib/cjs/utils/consts'; import { expect, test } from '@jest/globals'; -import { - INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN, - NETWORK, -} from '@wormhole-foundation/wormhole-monitor-common'; +import { INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN } from '@wormhole-foundation/wormhole-monitor-common'; import { Block, EVMWatcher, LOG_MESSAGE_PUBLISHED_TOPIC } from '../EVMWatcher'; const initialAvalancheBlock = Number( - INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN[NETWORK.MAINNET].avalanche -); -const initialCeloBlock = Number( - INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN[NETWORK.MAINNET].celo -); -const initialOasisBlock = Number( - INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN[NETWORK.MAINNET].oasis -); -const initialKaruraBlock = Number( - INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN[NETWORK.MAINNET].karura + INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN['mainnet'].avalanche ); +const initialCeloBlock = Number(INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN['mainnet'].celo); +const initialOasisBlock = Number(INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN['mainnet'].oasis); +const initialKaruraBlock = Number(INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN['mainnet'].karura); jest.setTimeout(60000); test('getBlock by tag', async () => { - const watcher = new EVMWatcher(NETWORK.MAINNET, 'avalanche'); + const watcher = new EVMWatcher('mainnet', 'avalanche'); const block = await watcher.getBlock('latest'); expect(block.number).toBeGreaterThan(initialAvalancheBlock); expect(block.timestamp).toBeGreaterThan(1671672811); @@ -30,7 +21,7 @@ test('getBlock by tag', async () => { }); test('getBlock by number', async () => { - const watcher = new EVMWatcher(NETWORK.MAINNET, 'avalanche'); + const watcher = new EVMWatcher('mainnet', 'avalanche'); const block = await watcher.getBlock(initialAvalancheBlock); expect(block.number).toEqual(initialAvalancheBlock); expect(block.hash).toEqual('0x33b358fe68a2a11b6a5a5969f29f9223001e36a5d719734ba542b238d397f14e'); @@ -39,7 +30,7 @@ test('getBlock by number', async () => { }); test('getBlocks', async () => { - const watcher = new EVMWatcher(NETWORK.MAINNET, 'avalanche'); + const watcher = new EVMWatcher('mainnet', 'avalanche'); const blocks = await watcher.getBlocks( initialAvalancheBlock, initialAvalancheBlock + watcher.maximumBatchSize - 1 @@ -59,7 +50,7 @@ test('getBlocks', async () => { }); test('getLogs', async () => { - const watcher = new EVMWatcher(NETWORK.MAINNET, 'avalanche'); + const watcher = new EVMWatcher('mainnet', 'avalanche'); const logs = await watcher.getLogs(9743300, 9743399, CONTRACTS.MAINNET.avalanche.core, [ LOG_MESSAGE_PUBLISHED_TOPIC, ]); @@ -72,13 +63,13 @@ test('getLogs', async () => { }); test('getFinalizedBlockNumber', async () => { - const watcher = new EVMWatcher(NETWORK.MAINNET, 'avalanche'); + const watcher = new EVMWatcher('mainnet', 'avalanche'); const blockNumber = await watcher.getFinalizedBlockNumber(); expect(blockNumber).toBeGreaterThan(initialAvalancheBlock); }); test('getMessagesForBlocks', async () => { - const watcher = new EVMWatcher(NETWORK.MAINNET, 'avalanche'); + const watcher = new EVMWatcher('mainnet', 'avalanche'); const vaasByBlock = await watcher.getMessagesForBlocks(9743300, 9743399); const entries = Object.entries(vaasByBlock); expect(entries.length).toEqual(100); @@ -93,7 +84,7 @@ test('getMessagesForBlocks', async () => { }); test('getBlock by tag (Oasis compatibility)', async () => { - const watcher = new EVMWatcher(NETWORK.MAINNET, 'oasis'); + const watcher = new EVMWatcher('mainnet', 'oasis'); const block = await watcher.getBlock('latest'); expect(block.number).toBeGreaterThan(initialOasisBlock); expect(block.timestamp).toBeGreaterThan(3895665); @@ -101,7 +92,7 @@ test('getBlock by tag (Oasis compatibility)', async () => { }); test('getBlock by tag (Celo compatibility)', async () => { - const watcher = new EVMWatcher(NETWORK.MAINNET, 'celo'); + const watcher = new EVMWatcher('mainnet', 'celo'); const block = await watcher.getBlock('latest'); expect(block.number).toBeGreaterThan(initialCeloBlock); expect(block.timestamp).toBeGreaterThan(1671672811); @@ -109,7 +100,7 @@ test('getBlock by tag (Celo compatibility)', async () => { }); test('getBlock by number (Celo compatibility)', async () => { - const watcher = new EVMWatcher(NETWORK.MAINNET, 'celo'); + const watcher = new EVMWatcher('mainnet', 'celo'); const block = await watcher.getBlock(initialCeloBlock); expect(block.number).toEqual(initialCeloBlock); expect(block.timestamp).toEqual(1652314820); @@ -117,7 +108,7 @@ test('getBlock by number (Celo compatibility)', async () => { }); test('getMessagesForBlocks (Celo compatibility)', async () => { - const watcher = new EVMWatcher(NETWORK.MAINNET, 'celo'); + const watcher = new EVMWatcher('mainnet', 'celo'); const vaasByBlock = await watcher.getMessagesForBlocks(13322450, 13322549); const entries = Object.entries(vaasByBlock); expect(entries.length).toEqual(100); @@ -132,7 +123,7 @@ test('getMessagesForBlocks (Celo compatibility)', async () => { }); test('getBlock by number (Karura compatibility)', async () => { - const watcher = new EVMWatcher(NETWORK.MAINNET, 'karura'); + const watcher = new EVMWatcher('mainnet', 'karura'); const latestBlock = await watcher.getFinalizedBlockNumber(); const moreRecentBlockNumber = 4646601; // block { @@ -148,7 +139,7 @@ test('getBlock by number (Karura compatibility)', async () => { }); test('getMessagesForBlocks (Karura compatibility)', async () => { - const watcher = new EVMWatcher(NETWORK.MAINNET, 'karura'); + const watcher = new EVMWatcher('mainnet', 'karura'); const vaasByBlock = await watcher.getMessagesForBlocks(4582511, 4582513); const entries = Object.entries(vaasByBlock); console.log('entries', entries); @@ -161,7 +152,7 @@ test('getMessagesForBlocks (Karura compatibility)', async () => { }); test('getMessagesForBlocks (Karura compatibility 2)', async () => { - const watcher = new EVMWatcher(NETWORK.MAINNET, 'karura'); + const watcher = new EVMWatcher('mainnet', 'karura'); await watcher.getFinalizedBlockNumber(); // This has the side effect of initializing the latestFinalizedBlockNumber const vaasByBlock = await watcher.getMessagesForBlocks(4595356, 4595358); const entries = Object.entries(vaasByBlock); @@ -171,7 +162,7 @@ test('getMessagesForBlocks (Karura compatibility 2)', async () => { // skipped as it was timing out the test test.skip('getBlock (Karura compatibility)', async () => { - const watcher = new EVMWatcher(NETWORK.MAINNET, 'karura'); + const watcher = new EVMWatcher('mainnet', 'karura'); await watcher.getFinalizedBlockNumber(); // This has the side effect of initializing the latestFinalizedBlockNumber let block: Block = await watcher.getBlock(4582512); // 6969 block console.log('block', block); diff --git a/watcher/src/watchers/__tests__/MoonbeamWatcher.test.ts b/watcher/src/watchers/__tests__/MoonbeamWatcher.test.ts index 76e2711c..363cdf56 100644 --- a/watcher/src/watchers/__tests__/MoonbeamWatcher.test.ts +++ b/watcher/src/watchers/__tests__/MoonbeamWatcher.test.ts @@ -1,18 +1,15 @@ import { expect, jest, test } from '@jest/globals'; -import { - INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN, - NETWORK, -} from '@wormhole-foundation/wormhole-monitor-common'; +import { INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN } from '@wormhole-foundation/wormhole-monitor-common'; import { MoonbeamWatcher } from '../MoonbeamWatcher'; jest.setTimeout(60000); const initialMoonbeamBlock = Number( - INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN[NETWORK.MAINNET].moonbeam + INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN['mainnet'].moonbeam ); test('getFinalizedBlockNumber', async () => { - const watcher = new MoonbeamWatcher(NETWORK.MAINNET); + const watcher = new MoonbeamWatcher('mainnet'); const blockNumber = await watcher.getFinalizedBlockNumber(); expect(blockNumber).toBeGreaterThan(initialMoonbeamBlock); }); diff --git a/watcher/src/watchers/__tests__/NearWatcher.test.ts b/watcher/src/watchers/__tests__/NearWatcher.test.ts index 58973694..b666babe 100644 --- a/watcher/src/watchers/__tests__/NearWatcher.test.ts +++ b/watcher/src/watchers/__tests__/NearWatcher.test.ts @@ -1,9 +1,6 @@ import { CONTRACTS } from '@certusone/wormhole-sdk/lib/cjs/utils/consts'; import { describe, expect, jest, test } from '@jest/globals'; -import { - INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN, - NETWORK, -} from '@wormhole-foundation/wormhole-monitor-common/dist/consts'; +import { INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN } from '@wormhole-foundation/wormhole-monitor-common/dist/consts'; import { RPCS_BY_CHAIN } from '../../consts'; import { getNearProvider, getTransactionsByAccountId, NEAR_ARCHIVE_RPC } from '../../utils/near'; import { getMessagesFromBlockResults } from '../NearWatcher'; @@ -12,9 +9,9 @@ import { NearArchiveWatcher } from '../NearArchiveWatcher'; jest.setTimeout(60000); const INITIAL_NEAR_BLOCK = Number( - INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN[NETWORK.MAINNET].near ?? 0 + INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN['mainnet'].near ?? 0 ); -let archiveWatcher: NearArchiveWatcher = new NearArchiveWatcher(NETWORK.MAINNET); +let archiveWatcher: NearArchiveWatcher = new NearArchiveWatcher('mainnet'); test('getFinalizedBlockNumber', async () => { const blockNumber = await archiveWatcher.getFinalizedBlockNumber(); @@ -34,16 +31,13 @@ test.skip('getMessagesForBlocks', async () => { describe('getNearProvider', () => { test('with normal RPC', async () => { - const provider = await getNearProvider( - NETWORK.MAINNET, - RPCS_BY_CHAIN[NETWORK.MAINNET]['near']! - ); + const provider = await getNearProvider('mainnet', RPCS_BY_CHAIN['mainnet']['near']!); // grab last block from core contract expect(await provider.block({ finality: 'final' })).toBeTruthy(); }); test('with archive RPC', async () => { - const provider = await getNearProvider(NETWORK.MAINNET, NEAR_ARCHIVE_RPC); + const provider = await getNearProvider('mainnet', NEAR_ARCHIVE_RPC); // grab first block with activity from core contract expect( await provider.block({ blockId: 'Asie8hpJFKaipvw8jh1wPfBwwbjP6JUfsQdCuQvwr3Sz' }) @@ -82,7 +76,7 @@ describe('getMessagesFromBlockResults', () => { }); test.skip('with ArchiveProvider', async () => { - const provider = await getNearProvider(NETWORK.MAINNET, NEAR_ARCHIVE_RPC); + const provider = await getNearProvider('mainnet', NEAR_ARCHIVE_RPC); const messages = await getMessagesFromBlockResults(provider, [ await provider.block({ blockId: 'Bzjemj99zxe1h8kVp8H2hwVifmbQL8HT34LyPHzEK5qp' }), await provider.block({ blockId: '4SHFxSo8DdP8DhMauS5iFqfmdLwLET3W3e8Lg9PFvBSn' }), diff --git a/watcher/src/watchers/__tests__/OptimismWatcher.test.ts b/watcher/src/watchers/__tests__/OptimismWatcher.test.ts index f4a0d5d0..872e5e69 100644 --- a/watcher/src/watchers/__tests__/OptimismWatcher.test.ts +++ b/watcher/src/watchers/__tests__/OptimismWatcher.test.ts @@ -1,25 +1,22 @@ import { expect, jest, test } from '@jest/globals'; -import { - INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN, - NETWORK, -} from '@wormhole-foundation/wormhole-monitor-common'; +import { INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN } from '@wormhole-foundation/wormhole-monitor-common'; import { EVMWatcher } from '../EVMWatcher'; jest.setTimeout(60000); const initialOptimismBlock = Number( - INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN[NETWORK.MAINNET].optimism + INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN['mainnet'].optimism ); test('getFinalizedBlockNumber', async () => { - const watcher = new EVMWatcher(NETWORK.MAINNET, 'optimism'); + const watcher = new EVMWatcher('mainnet', 'optimism'); const blockNumber = await watcher.getFinalizedBlockNumber(); console.log('blockNumber', blockNumber); expect(blockNumber).toBeGreaterThan(105235062); }); test('getMessagesForBlocks', async () => { - const watcher = new EVMWatcher(NETWORK.MAINNET, 'optimism'); + const watcher = new EVMWatcher('mainnet', 'optimism'); const vaasByBlock = await watcher.getMessagesForBlocks(105235070, 105235080); expect(vaasByBlock).toMatchObject({ '105235070/2023-06-06T16:28:37.000Z': [], diff --git a/watcher/src/watchers/__tests__/PolygonWatcher.test.ts b/watcher/src/watchers/__tests__/PolygonWatcher.test.ts index adc0e8dd..b4d809cf 100644 --- a/watcher/src/watchers/__tests__/PolygonWatcher.test.ts +++ b/watcher/src/watchers/__tests__/PolygonWatcher.test.ts @@ -1,18 +1,15 @@ import { expect, jest, test } from '@jest/globals'; -import { - INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN, - NETWORK, -} from '@wormhole-foundation/wormhole-monitor-common'; +import { INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN } from '@wormhole-foundation/wormhole-monitor-common'; import { PolygonWatcher } from '../PolygonWatcher'; jest.setTimeout(60000); const initialPolygonBlock = Number( - INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN[NETWORK.MAINNET].polygon + INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN['mainnet'].polygon ); test('getFinalizedBlockNumber', async () => { - const watcher = new PolygonWatcher(NETWORK.MAINNET); + const watcher = new PolygonWatcher('mainnet'); const blockNumber = await watcher.getFinalizedBlockNumber(); expect(blockNumber).toBeGreaterThan(initialPolygonBlock); }); diff --git a/watcher/src/watchers/__tests__/SolanaWatcher.test.ts b/watcher/src/watchers/__tests__/SolanaWatcher.test.ts index ccaaac10..599fd934 100644 --- a/watcher/src/watchers/__tests__/SolanaWatcher.test.ts +++ b/watcher/src/watchers/__tests__/SolanaWatcher.test.ts @@ -1,24 +1,21 @@ import { expect, jest, test } from '@jest/globals'; -import { - INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN, - NETWORK, -} from '@wormhole-foundation/wormhole-monitor-common/dist/consts'; +import { INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN } from '@wormhole-foundation/wormhole-monitor-common/dist/consts'; import { SolanaWatcher } from '../SolanaWatcher'; jest.setTimeout(60000); const INITIAL_SOLANA_BLOCK = Number( - INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN[NETWORK.MAINNET].solana ?? 0 + INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN['mainnet'].solana ?? 0 ); test('getFinalizedBlockNumber', async () => { - const watcher = new SolanaWatcher(NETWORK.MAINNET); + const watcher = new SolanaWatcher('mainnet'); const blockNumber = await watcher.getFinalizedBlockNumber(); expect(blockNumber).toBeGreaterThan(INITIAL_SOLANA_BLOCK); }); test('getMessagesForBlocks - single block', async () => { - const watcher = new SolanaWatcher(NETWORK.MAINNET); + const watcher = new SolanaWatcher('mainnet'); const messages = await watcher.getMessagesForBlocks(170799004, 170799004); expect(Object.keys(messages).length).toBe(1); expect(messages).toMatchObject({ @@ -34,21 +31,21 @@ test('getMessagesForBlocks - single block', async () => { // temporary skip due to SolanaJSONRPCError: failed to get confirmed block: Block 171774030 cleaned up, does not exist on node. First available block: 176896202 test('getMessagesForBlocks - fromSlot is skipped slot', async () => { - const watcher = new SolanaWatcher(NETWORK.MAINNET); + const watcher = new SolanaWatcher('mainnet'); const messages = await watcher.getMessagesForBlocks(171774030, 171774032); // 171774024 - 171774031 are skipped expect(Object.keys(messages).length).toBe(1); expect(messages).toMatchObject({ '171774032/2023-01-10T13:36:39.000Z': [] }); }); test('getMessagesForBlocks - toSlot is skipped slot', async () => { - const watcher = new SolanaWatcher(NETWORK.MAINNET); + const watcher = new SolanaWatcher('mainnet'); const messages = await watcher.getMessagesForBlocks(171774023, 171774025); expect(messages).toMatchObject({ '171774025/2023-01-10T13:36:34.000Z': [] }); }); test('getMessagesForBlocks - empty block', async () => { // Even if there are no messages, last block should still be returned - const watcher = new SolanaWatcher(NETWORK.MAINNET); + const watcher = new SolanaWatcher('mainnet'); const messages = await watcher.getMessagesForBlocks(170979766, 170979766); expect(Object.keys(messages).length).toBe(1); expect(messages).toMatchObject({ '170979766/2023-01-05T18:40:25.000Z': [] }); @@ -56,7 +53,7 @@ test('getMessagesForBlocks - empty block', async () => { // temporary skip due to SolanaJSONRPCError: failed to get confirmed block: Block 174108865 cleaned up, does not exist on node. First available block: 176892532 test('getMessagesForBlocks - block with no transactions', async () => { - const watcher = new SolanaWatcher(NETWORK.MAINNET); + const watcher = new SolanaWatcher('mainnet'); expect(watcher.getMessagesForBlocks(174108861, 174108861)).rejects.toThrowError( 'solana: invalid block range' ); @@ -71,21 +68,21 @@ test('getMessagesForBlocks - block with no transactions', async () => { }); test('getMessagesForBlocks - multiple blocks', async () => { - const watcher = new SolanaWatcher(NETWORK.MAINNET); + const watcher = new SolanaWatcher('mainnet'); const messages = await watcher.getMessagesForBlocks(171050470, 171050474); expect(Object.keys(messages).length).toBe(2); expect(Object.values(messages).flat().length).toBe(2); }); test('getMessagesForBlocks - multiple blocks, last block empty', async () => { - const watcher = new SolanaWatcher(NETWORK.MAINNET); + const watcher = new SolanaWatcher('mainnet'); const messages = await watcher.getMessagesForBlocks(170823000, 170825000); expect(Object.keys(messages).length).toBe(3); expect(Object.values(messages).flat().length).toBe(2); // 2 messages, last block has no message }); test('getMessagesForBlocks - multiple blocks containing more than `getSignaturesLimit` WH transactions', async () => { - const watcher = new SolanaWatcher(NETWORK.MAINNET); + const watcher = new SolanaWatcher('mainnet'); watcher.getSignaturesLimit = 10; const messages = await watcher.getMessagesForBlocks(171582367, 171583452); expect(Object.keys(messages).length).toBe(3); @@ -93,7 +90,7 @@ test('getMessagesForBlocks - multiple blocks containing more than `getSignatures }); test('getMessagesForBlocks - multiple calls', async () => { - const watcher = new SolanaWatcher(NETWORK.MAINNET); + const watcher = new SolanaWatcher('mainnet'); const messages1 = await watcher.getMessagesForBlocks(171773021, 171773211); const messages2 = await watcher.getMessagesForBlocks(171773212, 171773250); const messages3 = await watcher.getMessagesForBlocks(171773251, 171773500); @@ -107,7 +104,7 @@ test('getMessagesForBlocks - multiple calls', async () => { }); test('getMessagesForBlocks - handle failed transactions', async () => { - const watcher = new SolanaWatcher(NETWORK.MAINNET); + const watcher = new SolanaWatcher('mainnet'); const messages = await watcher.getMessagesForBlocks(94401321, 94501321); expect(Object.keys(messages).length).toBe(6); expect(Object.values(messages).flat().length).toBe(5); diff --git a/watcher/src/watchers/__tests__/SuiWatcher.test.ts b/watcher/src/watchers/__tests__/SuiWatcher.test.ts index 4a076fea..1d03dd7d 100644 --- a/watcher/src/watchers/__tests__/SuiWatcher.test.ts +++ b/watcher/src/watchers/__tests__/SuiWatcher.test.ts @@ -1,18 +1,15 @@ import { expect, jest, test } from '@jest/globals'; -import { - INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN, - NETWORK, -} from '@wormhole-foundation/wormhole-monitor-common/dist/consts'; +import { INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN } from '@wormhole-foundation/wormhole-monitor-common/dist/consts'; import { SuiWatcher } from '../SuiWatcher'; jest.setTimeout(60000); const INITAL_SEQUENCE_NUMBER = Number( - INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN[NETWORK.MAINNET].sui ?? 1581000 + INITIAL_DEPLOYMENT_BLOCK_BY_NETWORK_AND_CHAIN['mainnet'].sui ?? 1581000 ); test('getFinalizedSequenceNumber', async () => { - const watcher = new SuiWatcher(NETWORK.MAINNET); + const watcher = new SuiWatcher('mainnet'); const blockNumber = await watcher.getFinalizedBlockNumber(); console.log('Received blockNumber:', blockNumber); expect(blockNumber).toBeGreaterThan(INITAL_SEQUENCE_NUMBER); @@ -21,7 +18,7 @@ test('getFinalizedSequenceNumber', async () => { // This test will fail as time goes on because getMessagesForBlocks() grabs the latest and // works backwards. This will cause a 429 until we clear that up. test.skip('getMessagesForBlocks', async () => { - const watcher = new SuiWatcher(NETWORK.MAINNET); + const watcher = new SuiWatcher('mainnet'); const messages = await watcher.getMessagesForBlocks(1581997, 1581997); console.log(messages); const entries = Object.entries(messages); diff --git a/watcher/src/watchers/utils.ts b/watcher/src/watchers/utils.ts index 285bdb6b..89c73060 100644 --- a/watcher/src/watchers/utils.ts +++ b/watcher/src/watchers/utils.ts @@ -14,9 +14,9 @@ import { SuiWatcher } from './SuiWatcher'; import { SeiExplorerWatcher } from './SeiExplorerWatcher'; import { WormchainWatcher } from './WormchainWatcher'; import { NearArchiveWatcher } from './NearArchiveWatcher'; -import { NETWORK } from '@wormhole-foundation/wormhole-monitor-common'; +import { Environment } from '@wormhole-foundation/wormhole-monitor-common'; -export function makeFinalizedWatcher(network: NETWORK, chainName: ChainName): Watcher { +export function makeFinalizedWatcher(network: Environment, chainName: ChainName): Watcher { if (chainName === 'solana') { return new SolanaWatcher(network); } else if (chainName === 'ethereum' || chainName === 'karura' || chainName === 'acala') {