UNPKG

zonder

Version:

Ergonomic multi-chain indexing framework with dual runtime support for Ponder and Envio.

98 lines (97 loc) 4.43 kB
import * as yaml from 'js-yaml'; import { safeWriteFileSync } from '../utils/safeWrite.js'; import { resolveMinStartBlock, resolveStartBlock } from '../zonder/resolveStartBlock.js'; import { formatEventSignature } from './formatEventSignature.js'; export function generateEnvioConfig(config, projectName = 'zonder-indexer') { const envioConfig = { name: projectName, description: 'Auto-generated Envio configuration from Zonder', field_selection: { transaction_fields: ['hash'], }, contracts: [], networks: [], unordered_multichain_mode: true, }; // Process contracts Object.entries(config.contracts || {}).forEach(([contractName, abi]) => { const events = abi.filter((item) => item.type === 'event'); const isFactoryDeployed = config.factoryDeployed?.[contractName]; // Only include contract if it has events (factory-deployed contracts with no events are useless) if (envioConfig.contracts && events.length > 0) { envioConfig.contracts.push({ name: contractName, handler: `./src/EventHandlers.ts`, events: events.map((event) => ({ event: formatEventSignature(event), })), }); } }); // Process networks Object.entries(config.chains || {}).forEach(([chainName, chain]) => { const chainId = chain.id; const addresses = config.addresses?.[chainName]; const networkContracts = []; // Find minimum start block for chain using resolver const minStartBlock = resolveMinStartBlock(config.startBlocks, chainName, addresses); // Track which contracts have been added const addedContracts = new Set(); // Add contracts with static addresses Object.entries(addresses || {}).forEach(([contractName, address]) => { if (address) { const contractStartBlock = resolveStartBlock(config.startBlocks, chainName, contractName); // Check if this is a factory-deployed contract const factoryConfig = config.factoryDeployed?.[contractName]; if (!factoryConfig) { networkContracts.push({ name: contractName, address: Array.isArray(address) ? address : [address], start_block: contractStartBlock, }); addedContracts.add(contractName); } } }); // Add ALL contracts that have events, whether they have addresses or not Object.entries(config.contracts || {}).forEach(([contractName, abi]) => { // Skip if already added if (addedContracts.has(contractName)) return; // Check if contract has events const hasEvents = abi.some((item) => item.type === 'event'); if (!hasEvents) return; const contractStartBlock = resolveStartBlock(config.startBlocks, chainName, contractName); // Add contract without address (for factory-deployed or contracts that need dynamic discovery) networkContracts.push({ name: contractName, // No address field for contracts without static addresses start_block: contractStartBlock, }); addedContracts.add(contractName); }); if (networkContracts.length > 0) { envioConfig.networks.push({ id: chainId, start_block: minStartBlock, // Use minimum start block as chain start block contracts: networkContracts, }); } }); // Convert to YAML const yamlContent = yaml.dump(envioConfig, { indent: 2, lineWidth: -1, noRefs: true, sortKeys: false, }); // Add schema reference at the top const schemaHeader = '# yaml-language-server: $schema=./node_modules/envio/evm.schema.json\n'; return schemaHeader + yamlContent; } // Script wrapper for CLI usage export function generateAndWriteEnvioConfig(config, outputPath = 'config.yaml', projectName = 'zonder-indexer', overwrite = false) { const yamlContent = generateEnvioConfig(config, projectName); safeWriteFileSync(outputPath, yamlContent, { overwrite }); }