From ef9f5f7a3fe026337d043e98e55fc4e84a06742e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A1n=20Jakub=20Nani=C5=A1ta?= Date: Thu, 30 Nov 2023 11:13:49 -0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=AA=9A=20OmniGraph=E2=84=A2=20formatting?= =?UTF-8?q?=20&=20checking=20utilities=20(#48)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/test-utils/src/arbitraries.ts | 4 +- .../test/oapp/config.test.ts | 21 +- .../src/omnigraph/builder.ts | 12 +- .../src/omnigraph/coordinates.ts | 50 +- .../src/omnigraph/types.ts | 10 +- .../test/omnigraph/coordinates.test.ts | 34 +- packages/ua-utils/src/omnigraph/builder.ts | 10 +- .../ua-utils/src/omnigraph/coordinates.ts | 12 + packages/ua-utils/src/omnigraph/format.ts | 9 + packages/ua-utils/src/omnigraph/index.ts | 1 + .../__snapshots__/format.test.ts.snap | 499 ++++++++++++++++++ .../ua-utils/test/omnigraph/builder.test.ts | 54 +- .../test/omnigraph/coordinates.test.ts | 30 +- .../ua-utils/test/omnigraph/format.test.ts | 44 ++ packages/utils-evm-hardhat/src/runtime.ts | 2 +- 15 files changed, 717 insertions(+), 75 deletions(-) create mode 100644 packages/ua-utils/src/omnigraph/format.ts create mode 100644 packages/ua-utils/test/omnigraph/__snapshots__/format.test.ts.snap create mode 100644 packages/ua-utils/test/omnigraph/format.test.ts diff --git a/packages/test-utils/src/arbitraries.ts b/packages/test-utils/src/arbitraries.ts index e111fc4a2..ee2837c8a 100644 --- a/packages/test-utils/src/arbitraries.ts +++ b/packages/test-utils/src/arbitraries.ts @@ -1,5 +1,5 @@ import fc from 'fast-check' -import { EndpointId } from '@layerzerolabs/lz-definitions' +import { EndpointId, Stage } from '@layerzerolabs/lz-definitions' import { ENDPOINT_IDS } from './constants' export const addressArbitrary = fc.string() @@ -7,3 +7,5 @@ export const addressArbitrary = fc.string() export const evmAddressArbitrary = fc.hexaString({ minLength: 40, maxLength: 40 }).map((address) => `0x${address}`) export const endpointArbitrary: fc.Arbitrary = fc.constantFrom(...ENDPOINT_IDS) + +export const stageArbitrary: fc.Arbitrary = fc.constantFrom(Stage.MAINNET, Stage.TESTNET, Stage.SANDBOX) diff --git a/packages/ua-utils-evm-hardhat-test/test/oapp/config.test.ts b/packages/ua-utils-evm-hardhat-test/test/oapp/config.test.ts index 6fa79fc3a..ef8d460b0 100644 --- a/packages/ua-utils-evm-hardhat-test/test/oapp/config.test.ts +++ b/packages/ua-utils-evm-hardhat-test/test/oapp/config.test.ts @@ -4,14 +4,8 @@ import { describe } from 'mocha' import hre from 'hardhat' import { configureOApp, OmniPoint } from '@layerzerolabs/ua-utils' import { OApp } from '@layerzerolabs/ua-utils-evm' -import { connectOmniContract } from '@layerzerolabs/utils-evm' -import { - createDeploymentFactory, - omniDeploymentToContract, - omniDeploymentToPoint, - OmniGraphHardhat, - OmniGraphBuilderHardhat, -} from '@layerzerolabs/ua-utils-evm-hardhat' +import { omniContractToPoint, connectOmniContract } from '@layerzerolabs/utils-evm' +import { createContractFactory, OmniGraphHardhat, OmniGraphBuilderHardhat } from '@layerzerolabs/ua-utils-evm-hardhat' import { EndpointId } from '@layerzerolabs/lz-definitions' describe('oapp/config', () => { @@ -47,14 +41,13 @@ describe('oapp/config', () => { // This is the required tooling we need to set up const providerFactory = createProviderFactory(hre) - const deploymentFactory = createDeploymentFactory(hre) - const builder = await OmniGraphBuilderHardhat.fromConfig(config, deploymentFactory) + const contractFactory = createContractFactory(hre) + const builder = await OmniGraphBuilderHardhat.fromConfig(config, contractFactory) // This so far the only non-oneliner, a function that returns an SDK for a contract on a network const sdkFactory = async (point: OmniPoint) => { const provider = await providerFactory(point.eid) - const deployment = await deploymentFactory(point) - const contract = omniDeploymentToContract(deployment) + const contract = await contractFactory(point) return new OApp(connectOmniContract(contract, provider)) } @@ -63,10 +56,10 @@ describe('oapp/config', () => { const transactions = await configureOApp(builder.graph, sdkFactory) // And finally the test assertions - const ethPoint = omniDeploymentToPoint(await deploymentFactory(ethContract)) + const ethPoint = omniContractToPoint(await contractFactory(ethContract)) const ethSdk = await sdkFactory(ethPoint) - const avaxPoint = omniDeploymentToPoint(await deploymentFactory(avaxContract)) + const avaxPoint = omniContractToPoint(await contractFactory(avaxContract)) const avaxSdk = await sdkFactory(avaxPoint) expect(transactions).to.eql([ diff --git a/packages/ua-utils-evm-hardhat/src/omnigraph/builder.ts b/packages/ua-utils-evm-hardhat/src/omnigraph/builder.ts index 49251cfb7..f9d71d88f 100644 --- a/packages/ua-utils-evm-hardhat/src/omnigraph/builder.ts +++ b/packages/ua-utils-evm-hardhat/src/omnigraph/builder.ts @@ -1,17 +1,17 @@ import { type OmniEdge, OmniGraphBuilder, type OmniNode } from '@layerzerolabs/ua-utils' -import type { OmniDeploymentFactory, OmniGraphHardhat } from './types' -import { omniDeploymentToPoint } from './coordinates' +import type { OmniContractFactory, OmniGraphHardhat } from './types' +import { omniContractToPoint } from '@layerzerolabs/utils-evm' export class OmniGraphBuilderHardhat extends OmniGraphBuilder { static async fromConfig( graph: OmniGraphHardhat, - deploymentFactory: OmniDeploymentFactory + contractFactory: OmniContractFactory ): Promise> { const builder = new OmniGraphBuilderHardhat() const nodes: OmniNode[] = await Promise.all( graph.contracts.map(async ({ contract, config }) => ({ - point: omniDeploymentToPoint(await deploymentFactory(contract)), + point: omniContractToPoint(await contractFactory(contract)), config, })) ) @@ -19,8 +19,8 @@ export class OmniGraphBuilderHardhat extends OmniGraph const edges: OmniEdge[] = await Promise.all( graph.connections.map(async ({ from, to, config }) => ({ vector: { - from: omniDeploymentToPoint(await deploymentFactory(from)), - to: omniDeploymentToPoint(await deploymentFactory(to)), + from: omniContractToPoint(await contractFactory(from)), + to: omniContractToPoint(await contractFactory(to)), }, config, })) diff --git a/packages/ua-utils-evm-hardhat/src/omnigraph/coordinates.ts b/packages/ua-utils-evm-hardhat/src/omnigraph/coordinates.ts index da61c9ce0..6c776d7e7 100644 --- a/packages/ua-utils-evm-hardhat/src/omnigraph/coordinates.ts +++ b/packages/ua-utils-evm-hardhat/src/omnigraph/coordinates.ts @@ -6,7 +6,7 @@ import pMemoize from 'p-memoize' import { OmniContract } from '@layerzerolabs/utils-evm' import { Contract } from '@ethersproject/contracts' import assert from 'assert' -import { OmniDeploymentFactory, OmniPointContractName, OmniPointHardhat } from './types' +import { OmniContractFactory } from './types' import { assertHardhatDeploy, createNetworkEnvironmentFactory } from '@layerzerolabs/utils-evm-hardhat' export interface OmniDeployment { @@ -21,36 +21,40 @@ export const omniDeploymentToContract = ({ eid, deployment }): OmniContract => ( contract: new Contract(deployment.address, deployment.abi), }) -export const isOmniPointContractName = (point: OmniPointHardhat): point is OmniPointContractName => - 'contractName' in point && typeof point.contractName === 'string' - -export const createDeploymentFactory = (hre: HardhatRuntimeEnvironment): OmniDeploymentFactory => { - assertHardhatDeploy(hre) - +export const createContractFactory = (hre: HardhatRuntimeEnvironment): OmniContractFactory => { const environmentFactory = createNetworkEnvironmentFactory(hre) - return pMemoize(async (point) => { - const env = await environmentFactory(point.eid) + return pMemoize(async ({ eid, address, contractName }) => { + const env = await environmentFactory(eid) assertHardhatDeploy(env) - let deployment: Deployment | null + assert( + contractName != null || address != null, + 'At least one of contractName, address must be specified for OmniPointHardhat' + ) + + // If we have both the contract name & address, we go off artifacts + if (contractName != null && address != null) { + const artifact = await env.deployments.getArtifact(contractName) + const contract = new Contract(address, artifact.abi) - if (isOmniPointContractName(point)) { - deployment = await env.deployments.getOrNull(point.contractName) + return { eid, contract } + } - assert( - deployment, - `Could not find a deployment for contract '${point.contractName}' on endpoint ${point.eid}` - ) - } else { - ;[deployment] = await env.deployments.getDeploymentsFromAddress(point.address) + // If we have the contract name but no address, we need to get it from the deployments by name + if (contractName != null && address == null) { + const deployment = await env.deployments.getOrNull(contractName) + assert(deployment != null, `Could not find a deployment for contract '${contractName}`) - assert( - deployment, - `Could not find a deployment for on address '${point.address}' and endpoint ${point.eid}` - ) + return omniDeploymentToContract({ eid, deployment }) } - return { eid: point.eid, deployment } + // And if we only have the address, we need to go get it from deployments by address + if (address != null) { + const [deployment] = await env.deployments.getDeploymentsFromAddress(address) + assert(deployment != null, `Could not find a deployment for address '${address}`) + + return omniDeploymentToContract({ eid, deployment }) + } }) } diff --git a/packages/ua-utils-evm-hardhat/src/omnigraph/types.ts b/packages/ua-utils-evm-hardhat/src/omnigraph/types.ts index 7914c28ea..d33d89bf8 100644 --- a/packages/ua-utils-evm-hardhat/src/omnigraph/types.ts +++ b/packages/ua-utils-evm-hardhat/src/omnigraph/types.ts @@ -1,12 +1,12 @@ import type { EndpointId } from '@layerzerolabs/lz-definitions' import { OmniDeployment } from './coordinates' import { OmniPoint } from '@layerzerolabs/ua-utils' +import { OmniContract } from '@layerzerolabs/utils-evm' -export type OmniPointHardhat = OmniPoint | OmniPointContractName - -export interface OmniPointContractName { +export interface OmniPointHardhat { eid: EndpointId - contractName: string + contractName?: string + address?: string } export interface OmniNodeHardhat { @@ -25,4 +25,4 @@ export interface OmniGraphHardhat connections: OmniEdgeHardhat[] } -export type OmniDeploymentFactory = (point: OmniPointHardhat) => OmniDeployment | Promise +export type OmniContractFactory = (point: OmniPointHardhat) => OmniContract | Promise diff --git a/packages/ua-utils-evm-hardhat/test/omnigraph/coordinates.test.ts b/packages/ua-utils-evm-hardhat/test/omnigraph/coordinates.test.ts index 714759b94..d05b7cde0 100644 --- a/packages/ua-utils-evm-hardhat/test/omnigraph/coordinates.test.ts +++ b/packages/ua-utils-evm-hardhat/test/omnigraph/coordinates.test.ts @@ -2,10 +2,12 @@ import fc from 'fast-check' import hre from 'hardhat' import { Deployment, DeploymentSubmission } from 'hardhat-deploy/dist/types' import { endpointArbitrary, evmAddressArbitrary } from '@layerzerolabs/test-utils' -import { OmniDeployment, createDeploymentFactory, omniDeploymentToContract, omniDeploymentToPoint } from '@/omnigraph' +import { OmniDeployment, createContractFactory, omniDeploymentToContract, omniDeploymentToPoint } from '@/omnigraph' import { EndpointId } from '@layerzerolabs/lz-definitions' import { createNetworkEnvironmentFactory } from '@layerzerolabs/utils-evm-hardhat' import { HardhatRuntimeEnvironment } from 'hardhat/types' +import { Contract } from '@ethersproject/contracts' +import { makeZero } from '@layerzerolabs/utils-evm' describe('omnigraph/coordinates', () => { describe('omniDeploymentToPoint', () => { @@ -36,7 +38,7 @@ describe('omnigraph/coordinates', () => { }) }) - describe('createDeploymentFactory', () => { + describe('createContractFactory', () => { // Hardhat deploy will try to get the chain ID from the RPC so we can't let it const mockSend = (env: HardhatRuntimeEnvironment) => { env.network.provider.send = jest.fn().mockResolvedValue(1) @@ -44,7 +46,7 @@ describe('omnigraph/coordinates', () => { describe('when called with OmniPointContractName', () => { it('should reject when eid does not exist', async () => { - const deploymentFactory = createDeploymentFactory(hre) + const deploymentFactory = createContractFactory(hre) await expect(() => deploymentFactory({ eid: EndpointId.CANTO_TESTNET, contractName: 'MyContract' }) @@ -53,7 +55,7 @@ describe('omnigraph/coordinates', () => { it('should reject when contract has not been deployed', async () => { const environmentFactory = createNetworkEnvironmentFactory(hre) - const deploymentFactory = createDeploymentFactory(hre) + const deploymentFactory = createContractFactory(hre) const env = await environmentFactory(EndpointId.ETHEREUM_MAINNET) mockSend(env) @@ -65,13 +67,16 @@ describe('omnigraph/coordinates', () => { it('should resolve when contract has been deployed', async () => { const environmentFactory = createNetworkEnvironmentFactory(hre) - const deploymentFactory = createDeploymentFactory(hre) + const deploymentFactory = createContractFactory(hre) const env = await environmentFactory(EndpointId.ETHEREUM_MAINNET) mockSend(env) // We'll create a dummy deployment first - await env.deployments.save('MyContract', {} as DeploymentSubmission) + await env.deployments.save('MyContract', { + address: makeZero(undefined), + abi: [], + } as DeploymentSubmission) // Then check whether the factory will get it for us const deployment = await deploymentFactory({ @@ -81,9 +86,7 @@ describe('omnigraph/coordinates', () => { expect(deployment).toEqual({ eid: EndpointId.ETHEREUM_MAINNET, - deployment: { - numDeployments: expect.any(Number), - }, + contract: expect.any(Contract), }) }) }) @@ -92,7 +95,7 @@ describe('omnigraph/coordinates', () => { it('should reject when eid does not exist', async () => { await fc.assert( fc.asyncProperty(evmAddressArbitrary, async (address) => { - const deploymentFactory = createDeploymentFactory(hre) + const deploymentFactory = createContractFactory(hre) await expect(() => deploymentFactory({ eid: EndpointId.CANTO_TESTNET, address }) @@ -104,7 +107,7 @@ describe('omnigraph/coordinates', () => { it('should reject when contract has not been deployed', async () => { await fc.assert( fc.asyncProperty(evmAddressArbitrary, async (address) => { - const deploymentFactory = createDeploymentFactory(hre) + const deploymentFactory = createContractFactory(hre) await expect(() => deploymentFactory({ eid: EndpointId.ETHEREUM_MAINNET, address }) @@ -117,13 +120,13 @@ describe('omnigraph/coordinates', () => { await fc.assert( fc.asyncProperty(evmAddressArbitrary, async (address) => { const environmentFactory = createNetworkEnvironmentFactory(hre) - const deploymentFactory = createDeploymentFactory(hre) + const deploymentFactory = createContractFactory(hre) const env = await environmentFactory(EndpointId.ETHEREUM_MAINNET) mockSend(env) // We'll create a dummy deployment with the specified address first - await env.deployments.save('MyContract', { address } as DeploymentSubmission) + await env.deployments.save('MyContract', { address, abi: [] } as DeploymentSubmission) // Then check whether the factory will get it for us const deployment = await deploymentFactory({ @@ -133,10 +136,7 @@ describe('omnigraph/coordinates', () => { expect(deployment).toEqual({ eid: EndpointId.ETHEREUM_MAINNET, - deployment: { - address, - numDeployments: expect.any(Number), - }, + contract: expect.any(Contract), }) }) ) diff --git a/packages/ua-utils/src/omnigraph/builder.ts b/packages/ua-utils/src/omnigraph/builder.ts index b205bb34a..fc4cf44c1 100644 --- a/packages/ua-utils/src/omnigraph/builder.ts +++ b/packages/ua-utils/src/omnigraph/builder.ts @@ -1,6 +1,7 @@ import assert from 'assert' -import { arePointsEqual, serializePoint, serializeVector } from './coordinates' +import { arePointsEqual, isVectorPossible, serializePoint, serializeVector } from './coordinates' import type { OmniEdge, OmniGraph, OmniNode, OmniPoint, OmniVector } from './types' +import { formatOmniPoint, formatOmniVector } from './format' export class OmniGraphBuilder { #nodes: Map> = new Map() @@ -8,10 +9,11 @@ export class OmniGraphBuilder { #edges: Map> = new Map() #assertCanAddEdge(edge: OmniEdge): void { - const label = serializeVector(edge.vector) - const from = serializePoint(edge.vector.from) + const label = formatOmniVector(edge.vector) + const from = formatOmniPoint(edge.vector.from) - assert(this.getNodeAt(edge.vector.from), `Cannot add edge '${label}': '${from}' is not in the graph`) + assert(isVectorPossible(edge.vector), `Cannot add edge ${label}: cannot connect the two endpoints`) + assert(this.getNodeAt(edge.vector.from), `Cannot add edge ${label}: ${from} is not in the graph`) } // .-.-. .-.-. .-.-. .-.-. .-.-. .-.-. .-.-. .-.- diff --git a/packages/ua-utils/src/omnigraph/coordinates.ts b/packages/ua-utils/src/omnigraph/coordinates.ts index acd7ecb68..ccfcd7c2d 100644 --- a/packages/ua-utils/src/omnigraph/coordinates.ts +++ b/packages/ua-utils/src/omnigraph/coordinates.ts @@ -1,3 +1,4 @@ +import { endpointIdToStage } from '@layerzerolabs/lz-definitions' import { OmniVector, OmniPoint, OmniNode } from './types' /** @@ -31,6 +32,17 @@ export const areSameEndpoint = (a: OmniPoint, b: OmniPoint): boolean => a.eid == export const areVectorsEqual = (a: OmniVector, b: OmniVector): boolean => arePointsEqual(a.from, b.from) && arePointsEqual(a.to, b.to) +/** + * Checks that a vector is _possible_ - i.e. connects two endpoints + * that can be connected in reality. + * + * @param vector `OmniVector` + * + * @returns `true` if two points of the vector can be connected in reality + */ +export const isVectorPossible = ({ from, to }: OmniVector): boolean => + endpointIdToStage(from.eid) === endpointIdToStage(to.eid) + /** * Serializes a point. Useful for when points need to be used in Map * where we cannot adjust the default behavior of using a reference equality diff --git a/packages/ua-utils/src/omnigraph/format.ts b/packages/ua-utils/src/omnigraph/format.ts new file mode 100644 index 000000000..abc1b9846 --- /dev/null +++ b/packages/ua-utils/src/omnigraph/format.ts @@ -0,0 +1,9 @@ +import { EndpointId } from '@layerzerolabs/lz-definitions' +import type { OmniPoint, OmniVector } from './types' + +export const formatEid = (eid: EndpointId): string => EndpointId[eid] ?? `Unknown EndpointId (${eid})` + +export const formatOmniPoint = ({ eid, address }: OmniPoint): string => `[${address} @ ${formatEid(eid)}]` + +export const formatOmniVector = ({ from, to }: OmniVector): string => + `${formatOmniPoint(from)} → ${formatOmniPoint(to)}` diff --git a/packages/ua-utils/src/omnigraph/index.ts b/packages/ua-utils/src/omnigraph/index.ts index 904d9de85..bced80524 100644 --- a/packages/ua-utils/src/omnigraph/index.ts +++ b/packages/ua-utils/src/omnigraph/index.ts @@ -1,4 +1,5 @@ export * from './builder' export * from './coordinates' +export * from './format' export * from './schema' export * from './types' diff --git a/packages/ua-utils/test/omnigraph/__snapshots__/format.test.ts.snap b/packages/ua-utils/test/omnigraph/__snapshots__/format.test.ts.snap new file mode 100644 index 000000000..4000d052b --- /dev/null +++ b/packages/ua-utils/test/omnigraph/__snapshots__/format.test.ts.snap @@ -0,0 +1,499 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`omnigraph/format formatEid should format 101 correctly 1`] = `"ETHEREUM_MAINNET"`; + +exports[`omnigraph/format formatEid should format 102 correctly 1`] = `"BSC_MAINNET"`; + +exports[`omnigraph/format formatEid should format 106 correctly 1`] = `"AVALANCHE_MAINNET"`; + +exports[`omnigraph/format formatEid should format 108 correctly 1`] = `"APTOS_MAINNET"`; + +exports[`omnigraph/format formatEid should format 109 correctly 1`] = `"POLYGON_MAINNET"`; + +exports[`omnigraph/format formatEid should format 110 correctly 1`] = `"ARBITRUM_MAINNET"`; + +exports[`omnigraph/format formatEid should format 111 correctly 1`] = `"OPTIMISM_MAINNET"`; + +exports[`omnigraph/format formatEid should format 112 correctly 1`] = `"FANTOM_MAINNET"`; + +exports[`omnigraph/format formatEid should format 114 correctly 1`] = `"SWIMMER_MAINNET"`; + +exports[`omnigraph/format formatEid should format 115 correctly 1`] = `"DFK_MAINNET"`; + +exports[`omnigraph/format formatEid should format 116 correctly 1`] = `"HARMONY_MAINNET"`; + +exports[`omnigraph/format formatEid should format 118 correctly 1`] = `"DEXALOT_MAINNET"`; + +exports[`omnigraph/format formatEid should format 125 correctly 1`] = `"CELO_MAINNET"`; + +exports[`omnigraph/format formatEid should format 126 correctly 1`] = `"MOONBEAM_MAINNET"`; + +exports[`omnigraph/format formatEid should format 138 correctly 1`] = `"FUSE_MAINNET"`; + +exports[`omnigraph/format formatEid should format 145 correctly 1`] = `"GNOSIS_MAINNET"`; + +exports[`omnigraph/format formatEid should format 148 correctly 1`] = `"SHRAPNEL_MAINNET"`; + +exports[`omnigraph/format formatEid should format 149 correctly 1`] = `"DOS_MAINNET"`; + +exports[`omnigraph/format formatEid should format 150 correctly 1`] = `"KLAYTN_MAINNET"`; + +exports[`omnigraph/format formatEid should format 151 correctly 1`] = `"METIS_MAINNET"`; + +exports[`omnigraph/format formatEid should format 152 correctly 1`] = `"INTAIN_MAINNET"`; + +exports[`omnigraph/format formatEid should format 153 correctly 1`] = `"COREDAO_MAINNET"`; + +exports[`omnigraph/format formatEid should format 154 correctly 1`] = `"GOERLI_MAINNET"`; + +exports[`omnigraph/format formatEid should format 155 correctly 1`] = `"OKX_MAINNET"`; + +exports[`omnigraph/format formatEid should format 158 correctly 1`] = `"ZKPOLYGON_MAINNET"`; + +exports[`omnigraph/format formatEid should format 159 correctly 1`] = `"CANTO_MAINNET"`; + +exports[`omnigraph/format formatEid should format 161 correctly 1`] = `"SEPOLIA_MAINNET"`; + +exports[`omnigraph/format formatEid should format 165 correctly 1`] = `"ZKSYNC_MAINNET"`; + +exports[`omnigraph/format formatEid should format 167 correctly 1`] = `"MOONRIVER_MAINNET"`; + +exports[`omnigraph/format formatEid should format 168 correctly 1`] = `"SOLANA_MAINNET"`; + +exports[`omnigraph/format formatEid should format 173 correctly 1`] = `"TENET_MAINNET"`; + +exports[`omnigraph/format formatEid should format 175 correctly 1`] = `"NOVA_MAINNET"`; + +exports[`omnigraph/format formatEid should format 176 correctly 1`] = `"METER_MAINNET"`; + +exports[`omnigraph/format formatEid should format 177 correctly 1`] = `"KAVA_MAINNET"`; + +exports[`omnigraph/format formatEid should format 181 correctly 1`] = `"MANTLE_MAINNET"`; + +exports[`omnigraph/format formatEid should format 182 correctly 1`] = `"HUBBLE_MAINNET"`; + +exports[`omnigraph/format formatEid should format 183 correctly 1`] = `"ZKCONSENSYS_MAINNET"`; + +exports[`omnigraph/format formatEid should format 184 correctly 1`] = `"BASE_MAINNET"`; + +exports[`omnigraph/format formatEid should format 195 correctly 1`] = `"ZORA_MAINNET"`; + +exports[`omnigraph/format formatEid should format 196 correctly 1`] = `"TOMO_MAINNET"`; + +exports[`omnigraph/format formatEid should format 197 correctly 1`] = `"LOOT_MAINNET"`; + +exports[`omnigraph/format formatEid should format 198 correctly 1`] = `"MERITCIRCLE_MAINNET"`; + +exports[`omnigraph/format formatEid should format 199 correctly 1`] = `"TELOS_MAINNET"`; + +exports[`omnigraph/format formatEid should format 202 correctly 1`] = `"OPBNB_MAINNET"`; + +exports[`omnigraph/format formatEid should format 205 correctly 1`] = `"LIF3_MAINNET"`; + +exports[`omnigraph/format formatEid should format 210 correctly 1`] = `"ASTAR_MAINNET"`; + +exports[`omnigraph/format formatEid should format 211 correctly 1`] = `"AURORA_MAINNET"`; + +exports[`omnigraph/format formatEid should format 212 correctly 1`] = `"CONFLUX_MAINNET"`; + +exports[`omnigraph/format formatEid should format 213 correctly 1`] = `"ORDERLY_MAINNET"`; + +exports[`omnigraph/format formatEid should format 214 correctly 1`] = `"SCROLL_MAINNET"`; + +exports[`omnigraph/format formatEid should format 215 correctly 1`] = `"EON_MAINNET"`; + +exports[`omnigraph/format formatEid should format 216 correctly 1`] = `"XPLA_MAINNET"`; + +exports[`omnigraph/format formatEid should format 217 correctly 1`] = `"MANTA_MAINNET"`; + +exports[`omnigraph/format formatEid should format 218 correctly 1`] = `"PGN_MAINNET"`; + +exports[`omnigraph/format formatEid should format 230 correctly 1`] = `"SHIMMER_MAINNET"`; + +exports[`omnigraph/format formatEid should format 10102 correctly 1`] = `"BSC_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10106 correctly 1`] = `"AVALANCHE_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10108 correctly 1`] = `"APTOS_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10109 correctly 1`] = `"POLYGON_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10112 correctly 1`] = `"FANTOM_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10115 correctly 1`] = `"DFK_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10118 correctly 1`] = `"DEXALOT_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10121 correctly 1`] = `"ETHEREUM_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10125 correctly 1`] = `"CELO_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10126 correctly 1`] = `"MOONBEAM_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10130 correctly 1`] = `"SWIMMER_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10132 correctly 1`] = `"OPTIMISM_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10133 correctly 1`] = `"HARMONY_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10138 correctly 1`] = `"FUSE_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10143 correctly 1`] = `"ARBITRUM_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10145 correctly 1`] = `"GNOSIS_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10150 correctly 1`] = `"KLAYTN_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10151 correctly 1`] = `"METIS_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10152 correctly 1`] = `"INTAIN_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10153 correctly 1`] = `"COREDAO_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10155 correctly 1`] = `"OKX_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10156 correctly 1`] = `"METER_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10157 correctly 1`] = `"ZKCONSENSYS_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10158 correctly 1`] = `"ZKPOLYGON_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10159 correctly 1`] = `"CANTO_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10160 correctly 1`] = `"BASE_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10161 correctly 1`] = `"SEPOLIA_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10162 correctly 1`] = `"DOS_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10164 correctly 1`] = `"SHRAPNEL_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10165 correctly 1`] = `"ZKSYNC_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10168 correctly 1`] = `"SOLANA_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10171 correctly 1`] = `"CATHAY_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10172 correctly 1`] = `"KAVA_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10173 correctly 1`] = `"TENET_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10177 correctly 1`] = `"BLOCKGEN_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10178 correctly 1`] = `"MERITCIRCLE_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10181 correctly 1`] = `"MANTLE_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10182 correctly 1`] = `"HUBBLE_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10191 correctly 1`] = `"AAVEGOTCHI_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10195 correctly 1`] = `"ZORA_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10196 correctly 1`] = `"TOMO_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10197 correctly 1`] = `"LOOT_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10199 correctly 1`] = `"TELOS_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10200 correctly 1`] = `"ORDERLY_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10201 correctly 1`] = `"AURORA_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10202 correctly 1`] = `"OPBNB_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10204 correctly 1`] = `"MONAD_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10205 correctly 1`] = `"LIF3_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10206 correctly 1`] = `"SPRUCE_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10207 correctly 1`] = `"PGJJTK_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10208 correctly 1`] = `"ODA_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10209 correctly 1`] = `"KIWI_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10210 correctly 1`] = `"ASTAR_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10211 correctly 1`] = `"CONFLUX_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10214 correctly 1`] = `"SCROLL_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10215 correctly 1`] = `"EON_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10216 correctly 1`] = `"XPLA_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10217 correctly 1`] = `"HOLESKY_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10218 correctly 1`] = `"INJECTIVE_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10219 correctly 1`] = `"IDEX_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10220 correctly 1`] = `"ZKATANA_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10221 correctly 1`] = `"MANTA_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10222 correctly 1`] = `"FRAME_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10223 correctly 1`] = `"PGN_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10224 correctly 1`] = `"POLYGONCDK_TESTNET"`; + +exports[`omnigraph/format formatEid should format 10230 correctly 1`] = `"SHIMMER_TESTNET"`; + +exports[`omnigraph/format formatEid should format 20008 correctly 1`] = `"APTOS_SANDBOX"`; + +exports[`omnigraph/format formatEid should format 20102 correctly 1`] = `"BSC_SANDBOX"`; + +exports[`omnigraph/format formatEid should format 20106 correctly 1`] = `"AVALANCHE_SANDBOX"`; + +exports[`omnigraph/format formatEid should format 20109 correctly 1`] = `"POLYGON_SANDBOX"`; + +exports[`omnigraph/format formatEid should format 20121 correctly 1`] = `"ETHEREUM_SANDBOX"`; + +exports[`omnigraph/format formatEid should format 30101 correctly 1`] = `"ETHEREUM_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30102 correctly 1`] = `"BSC_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30106 correctly 1`] = `"AVALANCHE_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30108 correctly 1`] = `"APTOS_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30109 correctly 1`] = `"POLYGON_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30110 correctly 1`] = `"ARBITRUM_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30111 correctly 1`] = `"OPTIMISM_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30112 correctly 1`] = `"FANTOM_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30114 correctly 1`] = `"SWIMMER_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30115 correctly 1`] = `"DFK_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30116 correctly 1`] = `"HARMONY_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30118 correctly 1`] = `"DEXALOT_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30125 correctly 1`] = `"CELO_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30126 correctly 1`] = `"MOONBEAM_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30138 correctly 1`] = `"FUSE_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30145 correctly 1`] = `"GNOSIS_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30148 correctly 1`] = `"SHRAPNEL_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30149 correctly 1`] = `"DOS_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30150 correctly 1`] = `"KLAYTN_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30151 correctly 1`] = `"METIS_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30152 correctly 1`] = `"INTAIN_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30153 correctly 1`] = `"COREDAO_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30154 correctly 1`] = `"GOERLI_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30155 correctly 1`] = `"OKX_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30158 correctly 1`] = `"ZKPOLYGON_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30159 correctly 1`] = `"CANTO_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30161 correctly 1`] = `"SEPOLIA_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30165 correctly 1`] = `"ZKSYNC_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30167 correctly 1`] = `"MOONRIVER_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30168 correctly 1`] = `"SOLANA_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30173 correctly 1`] = `"TENET_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30175 correctly 1`] = `"NOVA_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30176 correctly 1`] = `"METER_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30177 correctly 1`] = `"KAVA_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30181 correctly 1`] = `"MANTLE_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30182 correctly 1`] = `"HUBBLE_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30183 correctly 1`] = `"ZKCONSENSYS_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30184 correctly 1`] = `"BASE_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30195 correctly 1`] = `"ZORA_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30196 correctly 1`] = `"TOMO_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30197 correctly 1`] = `"LOOT_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30198 correctly 1`] = `"MERITCIRCLE_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30199 correctly 1`] = `"TELOS_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30202 correctly 1`] = `"OPBNB_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30205 correctly 1`] = `"LIF3_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30210 correctly 1`] = `"ASTAR_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30211 correctly 1`] = `"AURORA_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30212 correctly 1`] = `"CONFLUX_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30213 correctly 1`] = `"ORDERLY_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30214 correctly 1`] = `"SCROLL_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30215 correctly 1`] = `"EON_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30216 correctly 1`] = `"XPLA_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30217 correctly 1`] = `"MANTA_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30218 correctly 1`] = `"PGN_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 30230 correctly 1`] = `"SHIMMER_V2_MAINNET"`; + +exports[`omnigraph/format formatEid should format 40102 correctly 1`] = `"BSC_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40106 correctly 1`] = `"AVALANCHE_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40109 correctly 1`] = `"POLYGON_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40112 correctly 1`] = `"FANTOM_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40115 correctly 1`] = `"DFK_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40118 correctly 1`] = `"DEXALOT_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40121 correctly 1`] = `"ETHEREUM_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40125 correctly 1`] = `"CELO_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40126 correctly 1`] = `"MOONBEAM_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40132 correctly 1`] = `"OPTIMISM_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40133 correctly 1`] = `"HARMONY_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40138 correctly 1`] = `"FUSE_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40143 correctly 1`] = `"ARBITRUM_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40145 correctly 1`] = `"GNOSIS_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40150 correctly 1`] = `"KLAYTN_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40151 correctly 1`] = `"METIS_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40153 correctly 1`] = `"COREDAO_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40155 correctly 1`] = `"OKX_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40156 correctly 1`] = `"METER_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40157 correctly 1`] = `"ZKCONSENSYS_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40158 correctly 1`] = `"ZKPOLYGON_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40159 correctly 1`] = `"CANTO_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40160 correctly 1`] = `"BASE_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40161 correctly 1`] = `"SEPOLIA_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40162 correctly 1`] = `"DOS_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40164 correctly 1`] = `"SHRAPNEL_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40165 correctly 1`] = `"ZKSYNC_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40168 correctly 1`] = `"SOLANA_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40170 correctly 1`] = `"SCROLL_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40171 correctly 1`] = `"CATHAY_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40172 correctly 1`] = `"KAVA_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40173 correctly 1`] = `"TENET_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40177 correctly 1`] = `"BLOCKGEN_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40178 correctly 1`] = `"MERITCIRCLE_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40179 correctly 1`] = `"AAVEGOTCHI_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40181 correctly 1`] = `"MANTLE_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40182 correctly 1`] = `"HUBBLE_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40195 correctly 1`] = `"ZORA_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40196 correctly 1`] = `"TOMO_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40197 correctly 1`] = `"LOOT_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40199 correctly 1`] = `"TELOS_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40200 correctly 1`] = `"ORDERLY_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40201 correctly 1`] = `"AURORA_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40202 correctly 1`] = `"OPBNB_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40203 correctly 1`] = `"SHIMMER_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40204 correctly 1`] = `"MONAD_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40205 correctly 1`] = `"LIF3_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40206 correctly 1`] = `"SPRUCE_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40207 correctly 1`] = `"PGJJTK_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40208 correctly 1`] = `"ODA_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40209 correctly 1`] = `"KIWI_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40210 correctly 1`] = `"ASTAR_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40211 correctly 1`] = `"CONFLUX_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40215 correctly 1`] = `"EON_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40216 correctly 1`] = `"XPLA_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40217 correctly 1`] = `"HOLESKY_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40218 correctly 1`] = `"INJECTIVE_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40219 correctly 1`] = `"IDEX_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40220 correctly 1`] = `"ZKATANA_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40221 correctly 1`] = `"MANTA_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40222 correctly 1`] = `"FRAME_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40223 correctly 1`] = `"PGN_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 40224 correctly 1`] = `"POLYGONCDK_V2_TESTNET"`; + +exports[`omnigraph/format formatEid should format 50102 correctly 1`] = `"BSC_V2_SANDBOX"`; + +exports[`omnigraph/format formatEid should format 50106 correctly 1`] = `"AVALANCHE_V2_SANDBOX"`; + +exports[`omnigraph/format formatEid should format 50109 correctly 1`] = `"POLYGON_V2_SANDBOX"`; + +exports[`omnigraph/format formatEid should format 50121 correctly 1`] = `"ETHEREUM_V2_SANDBOX"`; + +exports[`omnigraph/format formatEid should format 50168 correctly 1`] = `"SOLANA_V2_SANDBOX"`; diff --git a/packages/ua-utils/test/omnigraph/builder.test.ts b/packages/ua-utils/test/omnigraph/builder.test.ts index ed6ff01aa..28cc90ded 100644 --- a/packages/ua-utils/test/omnigraph/builder.test.ts +++ b/packages/ua-utils/test/omnigraph/builder.test.ts @@ -1,7 +1,7 @@ import fc from 'fast-check' import { createNodeArbitrary, createEdgeArbitrary, pointArbitrary, vectorArbitrary } from '../__utils__/arbitraries' import { OmniGraphBuilder } from '@/omnigraph/builder' -import { arePointsEqual, areVectorsEqual } from '@/omnigraph' +import { arePointsEqual, areVectorsEqual, isVectorPossible } from '@/omnigraph' describe('omnigraph/builder', () => { const nodeConfigArbitrary = fc.anything() @@ -122,8 +122,6 @@ describe('omnigraph/builder', () => { fc.pre(!arePointsEqual(nodeA.point, nodeC.point)) fc.pre(!arePointsEqual(nodeB.point, nodeC.point)) - const builder = new OmniGraphBuilder() - const edgeAB = { vector: { from: nodeA.point, to: nodeB.point }, config: edgeConfig } const edgeAC = { vector: { from: nodeA.point, to: nodeC.point }, config: edgeConfig } const edgeBA = { vector: { from: nodeB.point, to: nodeA.point }, config: edgeConfig } @@ -131,6 +129,15 @@ describe('omnigraph/builder', () => { const edgeCA = { vector: { from: nodeC.point, to: nodeA.point }, config: edgeConfig } const edgeCB = { vector: { from: nodeC.point, to: nodeB.point }, config: edgeConfig } + fc.pre(isVectorPossible(edgeAB.vector)) + fc.pre(isVectorPossible(edgeAC.vector)) + fc.pre(isVectorPossible(edgeBA.vector)) + fc.pre(isVectorPossible(edgeBC.vector)) + fc.pre(isVectorPossible(edgeCA.vector)) + fc.pre(isVectorPossible(edgeCB.vector)) + + const builder = new OmniGraphBuilder() + builder .addNodes(nodeA, nodeB, nodeC) .addEdges(edgeAB, edgeAC, edgeBA, edgeBC, edgeCA, edgeCB) @@ -158,6 +165,27 @@ describe('omnigraph/builder', () => { it('should fail if from is not in the graph', () => { fc.assert( fc.property(edgeArbitrary, nodeConfigArbitrary, (edge, nodeConfig) => { + fc.pre(isVectorPossible(edge.vector)) + + const builder = new OmniGraphBuilder() + + builder + .addNodes( + { point: edge.vector.from, config: nodeConfig }, + { point: edge.vector.to, config: nodeConfig } + ) + .removeNodeAt(edge.vector.from) + + expect(() => builder.addEdges(edge)).toThrow() + }) + ) + }) + + it('should fail if vector is not possible', () => { + fc.assert( + fc.property(edgeArbitrary, nodeConfigArbitrary, (edge, nodeConfig) => { + fc.pre(!isVectorPossible(edge.vector)) + const builder = new OmniGraphBuilder() builder @@ -175,6 +203,8 @@ describe('omnigraph/builder', () => { it('should not fail if to is not in the graph', () => { fc.assert( fc.property(edgeArbitrary, nodeConfigArbitrary, (edge, nodeConfig) => { + fc.pre(isVectorPossible(edge.vector)) + const builder = new OmniGraphBuilder() builder @@ -193,6 +223,8 @@ describe('omnigraph/builder', () => { it('should add a single edge', () => { fc.assert( fc.property(edgeArbitrary, nodeConfigArbitrary, (edge, nodeConfig) => { + fc.pre(isVectorPossible(edge.vector)) + const builder = new OmniGraphBuilder() builder @@ -207,6 +239,8 @@ describe('omnigraph/builder', () => { it('should not add a duplicate edge', () => { fc.assert( fc.property(edgeArbitrary, nodeConfigArbitrary, (edge, nodeConfig) => { + fc.pre(isVectorPossible(edge.vector)) + const builder = new OmniGraphBuilder() builder @@ -226,6 +260,8 @@ describe('omnigraph/builder', () => { edgeConfigArbitrary, nodeConfigArbitrary, (vector, configA, configB, nodeConfig) => { + fc.pre(isVectorPossible(vector)) + const builder = new OmniGraphBuilder() const edgeA = { vector, config: configA } @@ -246,6 +282,8 @@ describe('omnigraph/builder', () => { it('should not do anything when there are no edges', () => { fc.assert( fc.property(edgeArbitrary, (edge) => { + fc.pre(isVectorPossible(edge.vector)) + const builder = new OmniGraphBuilder() builder.removeEdgeAt(edge.vector) @@ -257,6 +295,8 @@ describe('omnigraph/builder', () => { it('should return self', () => { fc.assert( fc.property(edgeArbitrary, (edge) => { + fc.pre(isVectorPossible(edge.vector)) + const builder = new OmniGraphBuilder() expect(builder.removeEdgeAt(edge.vector)).toBe(builder) @@ -267,6 +307,8 @@ describe('omnigraph/builder', () => { it('should remove a edge at a specified vector', () => { fc.assert( fc.property(edgeArbitrary, nodeConfigArbitrary, (edge, nodeConfig) => { + fc.pre(isVectorPossible(edge.vector)) + const builder = new OmniGraphBuilder() builder @@ -283,6 +325,8 @@ describe('omnigraph/builder', () => { it('should not remove edges at different vectors', () => { fc.assert( fc.property(edgeArbitrary, edgeArbitrary, nodeConfigArbitrary, (edgeA, edgeB, nodeConfig) => { + fc.pre(isVectorPossible(edgeA.vector)) + fc.pre(isVectorPossible(edgeB.vector)) fc.pre(!areVectorsEqual(edgeA.vector, edgeB.vector)) const builder = new OmniGraphBuilder() @@ -359,6 +403,7 @@ describe('omnigraph/builder', () => { fc.property(edgesArbitrary, nodeConfigArbitrary, (edges, nodeConfig) => { const edge = edges.at(-1) fc.pre(edge != null) + fc.pre(edges.map((e) => e.vector).every(isVectorPossible)) const builder = new OmniGraphBuilder() const nodes = edges.flatMap(({ vector: { from, to } }) => [ @@ -380,6 +425,7 @@ describe('omnigraph/builder', () => { fc.property(edgesArbitrary, nodeConfigArbitrary, (edges, nodeConfig) => { const edge = edges.at(-1) fc.pre(edge != null) + fc.pre(edges.map((e) => e.vector).every(isVectorPossible)) const builder = new OmniGraphBuilder() const nodes = edges.flatMap(({ vector: { from, to } }) => [ @@ -410,6 +456,7 @@ describe('omnigraph/builder', () => { fc.property(edgesArbitrary, nodeConfigArbitrary, (edges, nodeConfig) => { const edge = edges.at(-1) fc.pre(edge != null) + fc.pre(edges.map((e) => e.vector).every(isVectorPossible)) const builder = new OmniGraphBuilder() const nodes = edges.flatMap(({ vector: { from, to } }) => [ @@ -444,6 +491,7 @@ describe('omnigraph/builder', () => { fc.property(edgesArbitrary, nodeConfigArbitrary, (edges, nodeConfig) => { const edge = edges.at(-1) fc.pre(edge != null) + fc.pre(edges.map((e) => e.vector).every(isVectorPossible)) const builder = new OmniGraphBuilder() const nodes = edges.flatMap(({ vector: { from, to } }) => [ diff --git a/packages/ua-utils/test/omnigraph/coordinates.test.ts b/packages/ua-utils/test/omnigraph/coordinates.test.ts index 4241d3987..42f8b5dad 100644 --- a/packages/ua-utils/test/omnigraph/coordinates.test.ts +++ b/packages/ua-utils/test/omnigraph/coordinates.test.ts @@ -5,9 +5,11 @@ import { serializePoint, serializeVector, areSameEndpoint, + isVectorPossible, } from '@/omnigraph/coordinates' import { pointArbitrary, vectorArbitrary } from '../__utils__/arbitraries' -import { addressArbitrary, endpointArbitrary } from '@layerzerolabs/test-utils' +import { addressArbitrary, endpointArbitrary, stageArbitrary } from '@layerzerolabs/test-utils' +import { endpointIdToStage } from '@layerzerolabs/lz-definitions' describe('omnigraph/vector', () => { describe('assertions', () => { @@ -148,5 +150,31 @@ describe('omnigraph/vector', () => { ) }) }) + + describe('isVectorPossible', () => { + it('should return true if two points are on the same stage', () => { + fc.assert( + fc.property(endpointArbitrary, endpointArbitrary, addressArbitrary, (eid1, eid2, address) => { + fc.pre(endpointIdToStage(eid1) === endpointIdToStage(eid2)) + + expect( + isVectorPossible({ from: { eid: eid1, address }, to: { eid: eid2, address } }) + ).toBeTruthy() + }) + ) + }) + + it('should return false if two points are not on the same stage', () => { + fc.assert( + fc.property(endpointArbitrary, endpointArbitrary, addressArbitrary, (eid1, eid2, address) => { + fc.pre(endpointIdToStage(eid1) !== endpointIdToStage(eid2)) + + expect( + isVectorPossible({ from: { eid: eid1, address }, to: { eid: eid2, address } }) + ).toBeFalsy() + }) + ) + }) + }) }) }) diff --git a/packages/ua-utils/test/omnigraph/format.test.ts b/packages/ua-utils/test/omnigraph/format.test.ts new file mode 100644 index 000000000..2b2264acd --- /dev/null +++ b/packages/ua-utils/test/omnigraph/format.test.ts @@ -0,0 +1,44 @@ +import { formatEid, formatOmniPoint, formatOmniVector } from '@/omnigraph/format' +import { EndpointId } from '@layerzerolabs/lz-definitions' +import { ENDPOINT_IDS } from '@layerzerolabs/test-utils' +import fc from 'fast-check' +import { pointArbitrary, vectorArbitrary } from '../__utils__/arbitraries' + +describe('omnigraph/format', () => { + describe('formatEid', () => { + it.each(ENDPOINT_IDS)(`should format %d correctly`, (eid) => { + expect(formatEid(eid)).toMatchSnapshot() + }) + + it('should format invalid EndpointId correctly', () => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + fc.property(fc.anything(), (eid: any) => { + fc.pre(!(eid in EndpointId)) + + expect(formatEid(eid)).toBe(`Unknown EndpointId (${eid})`) + }) + }) + }) + + describe('formatOmniPoint', () => { + it('should just work innit', () => { + fc.assert( + fc.property(pointArbitrary, (point) => { + expect(formatOmniPoint(point)).toBe(`[${point.address} @ ${formatEid(point.eid)}]`) + }) + ) + }) + }) + + describe('formatOmniVector', () => { + it('should just work innit', () => { + fc.assert( + fc.property(vectorArbitrary, (vector) => { + expect(formatOmniVector(vector)).toBe( + `${formatOmniPoint(vector.from)} → ${formatOmniPoint(vector.to)}` + ) + }) + ) + }) + }) +}) diff --git a/packages/utils-evm-hardhat/src/runtime.ts b/packages/utils-evm-hardhat/src/runtime.ts index dda1fbb66..ab2a1901d 100644 --- a/packages/utils-evm-hardhat/src/runtime.ts +++ b/packages/utils-evm-hardhat/src/runtime.ts @@ -1,4 +1,4 @@ -import type { HardhatRuntimeEnvironment, EIP1193Provider, Network } from 'hardhat/types' +import type { HardhatRuntimeEnvironment, EIP1193Provider } from 'hardhat/types' import pMemoize from 'p-memoize' import { Web3Provider } from '@ethersproject/providers'