zonder
Version:
Ergonomic multi-chain indexing framework with dual runtime support for Ponder and Envio.
54 lines (53 loc) • 2.39 kB
JavaScript
import { safeWriteFileSync } from '../utils/safeWrite.js';
import { solidityTypeToPgType } from './solidityTypeToPgType.js';
export function generateSchema(configOrContracts) {
// Handle both full config and just contracts
const contracts = 'contracts' in configOrContracts ? configOrContracts.contracts : configOrContracts;
const autogenerated = `// This file is auto-generated by zonder. Do not edit manually.\n`;
const imports = `import { index, onchainTable } from 'ponder';\n`;
const metadataSchema = `const metadataSchema = (t: any) => {
return {
id: t.text().primaryKey(),
chainId: t.integer().notNull(),
txHash: t.hex().notNull(),
blockNumber: t.bigint().notNull(),
timestamp: t.bigint().notNull(),
logIndex: t.integer().notNull(),
logAddress: t.hex().notNull(),
};
};`;
let eventTables = ``;
Object.entries(contracts).forEach(([contractName, abi]) => {
const events = abi.filter((e) => e.type === 'event');
if (!events.length)
return;
eventTables += `\nexport const ${contractName} = {`;
events.forEach((event) => {
const tableName = `${contractName}_${event.name}`;
const eventArgs = event.inputs
.map((input) => ` evt_${input.name}: t.${solidityTypeToPgType(input.type)}().notNull(),`)
.join('\n');
const addressIndexes = event.inputs
.filter((input) => input.type === 'address')
.map((input) => ` evt_${input.name}Idx: index().using('btree', t.chainId, t.evt_${input.name}),`)
.join('\n');
eventTables += `
${event.name}: onchainTable(\'${tableName}\', (t) => ({
...metadataSchema(t),
${eventArgs}
}),
(t) => ({
chainIdTimestampIdx: index().using('btree', t.chainId, t.timestamp),
${addressIndexes}
})),`;
});
eventTables += `\n};\n\n`;
events.forEach((event) => (eventTables += `export const ${contractName}_${event.name} = ${contractName}.${event.name};\n`));
});
return `${autogenerated}\n${imports}\n${metadataSchema}\n${eventTables}`;
}
// Script wrapper for CLI usage
export function generateAndWriteSchema(config, outputPath = 'ponder.schema.ts', overwrite = false) {
const schemaContent = generateSchema(config);
safeWriteFileSync(outputPath, schemaContent, { overwrite });
}