/** * Synor Compiler SDK Examples for JavaScript/TypeScript * * Demonstrates smart contract compilation and analysis: * - WASM contract compilation and optimization * - ABI extraction and encoding * - Contract analysis and security scanning * - Validation and verification */ import * as fs from 'fs'; import { SynorCompiler, CompilerConfig, OptimizationLevel, StripOptions, } from '../src/compiler'; async function main() { // Initialize client const config: CompilerConfig = { apiKey: process.env.SYNOR_API_KEY || 'your-api-key', endpoint: 'https://compiler.synor.io/v1', timeout: 60000, retries: 3, debug: false, defaultOptimizationLevel: OptimizationLevel.Size, maxContractSize: 256 * 1024, useWasmOpt: true, validate: true, extractMetadata: true, generateAbi: true, }; const compiler = new SynorCompiler(config); try { // Check service health const healthy = await compiler.healthCheck(); console.log(`Service healthy: ${healthy}\n`); // Example 1: Compile a contract await compileContractExample(compiler); // Example 2: Development vs Production compilation await compilationModesExample(compiler); // Example 3: ABI operations await abiExample(compiler); // Example 4: Contract analysis await analysisExample(compiler); // Example 5: Validation await validationExample(compiler); // Example 6: Security scanning await securityExample(compiler); } finally { compiler.close(); } } /** * Basic contract compilation */ async function compileContractExample(compiler: SynorCompiler): Promise { console.log('=== Contract Compilation ==='); // In production, load from file: // const wasm = fs.readFileSync('my_contract.wasm'); // For demonstration, create a minimal WASM module const wasm = createMinimalWasm(); const result = await compiler.compile(wasm, { optimizationLevel: OptimizationLevel.Size, useWasmOpt: true, validate: true, extractMetadata: true, generateAbi: true, stripOptions: { stripDebug: true, stripProducers: true, stripNames: true, stripCustom: true, stripUnused: true, preserveSections: [], }, }); console.log('Compilation result:'); console.log(` Contract ID: ${result.contractId}`); console.log(` Code hash: ${result.codeHash}`); console.log(` Original size: ${result.originalSize} bytes`); console.log(` Optimized size: ${result.optimizedSize} bytes`); console.log(` Size reduction: ${result.sizeReduction.toFixed(1)}%`); console.log(` Estimated deploy gas: ${result.estimatedDeployGas}`); if (result.metadata) { console.log('\nMetadata:'); console.log(` Name: ${result.metadata.name}`); console.log(` Version: ${result.metadata.version}`); console.log(` SDK Version: ${result.metadata.sdkVersion}`); } if (result.abi) { console.log('\nABI:'); console.log(` Functions: ${result.abi.functions?.length || 0}`); console.log(` Events: ${result.abi.events?.length || 0}`); console.log(` Errors: ${result.abi.errors?.length || 0}`); } console.log(''); } /** * Development vs Production compilation modes */ async function compilationModesExample(compiler: SynorCompiler): Promise { console.log('=== Compilation Modes ==='); const wasm = createMinimalWasm(); // Development mode: fast compilation, debugging support console.log('Development mode:'); const devResult = await compiler.contracts.compileDev(wasm); console.log(` Size: ${devResult.optimizedSize} bytes`); console.log(` Optimization: none`); // Production mode: maximum optimization console.log('\nProduction mode:'); const prodResult = await compiler.contracts.compileProduction(wasm); console.log(` Size: ${prodResult.optimizedSize} bytes`); console.log(` Optimization: aggressive`); console.log(` Size savings: ${(devResult.optimizedSize - prodResult.optimizedSize)} bytes`); // Custom optimization levels console.log('\nOptimization levels:'); const levels = [ OptimizationLevel.None, OptimizationLevel.Basic, OptimizationLevel.Size, OptimizationLevel.Aggressive, ]; for (const level of levels) { const result = await compiler.compile(wasm, { optimizationLevel: level }); console.log(` ${level}: ${result.optimizedSize} bytes`); } console.log(''); } /** * ABI extraction and encoding */ async function abiExample(compiler: SynorCompiler): Promise { console.log('=== ABI Operations ==='); const wasm = createMinimalWasm(); // Extract ABI from WASM const abi = await compiler.abi.extract(wasm); console.log(`Contract: ${abi.name}`); console.log(`Version: ${abi.version}`); // List functions if (abi.functions && abi.functions.length > 0) { console.log('\nFunctions:'); for (const func of abi.functions) { const inputs = func.inputs?.map(i => `${i.name}: ${i.type.typeName}`).join(', ') || ''; const outputs = func.outputs?.map(o => o.type.typeName).join(', ') || 'void'; const modifiers = [ func.view ? 'view' : '', func.payable ? 'payable' : '', ].filter(Boolean).join(' '); console.log(` ${func.name}(${inputs}) -> ${outputs} ${modifiers}`); console.log(` Selector: ${func.selector}`); } } // List events if (abi.events && abi.events.length > 0) { console.log('\nEvents:'); for (const event of abi.events) { const params = event.params?.map(p => { const indexed = p.indexed ? 'indexed ' : ''; return `${indexed}${p.name}: ${p.type.typeName}`; }).join(', ') || ''; console.log(` ${event.name}(${params})`); console.log(` Topic: ${event.topic}`); } } // Encode a function call if (abi.functions && abi.functions.length > 0) { const func = abi.functions[0]; const encoded = await compiler.abi.encodeCall(func, ['arg1', 'arg2']); console.log(`\nEncoded call to ${func.name}: ${encoded}`); // Decode a result const decoded = await compiler.abi.decodeResult(func, encoded); console.log(`Decoded result: ${JSON.stringify(decoded)}`); } console.log(''); } /** * Contract analysis */ async function analysisExample(compiler: SynorCompiler): Promise { console.log('=== Contract Analysis ==='); const wasm = createMinimalWasm(); // Full analysis const analysis = await compiler.analysis.analyze(wasm); // Size breakdown if (analysis.sizeBreakdown) { console.log('Size breakdown:'); console.log(` Code: ${analysis.sizeBreakdown.code} bytes`); console.log(` Data: ${analysis.sizeBreakdown.data} bytes`); console.log(` Functions: ${analysis.sizeBreakdown.functions} bytes`); console.log(` Memory: ${analysis.sizeBreakdown.memory} bytes`); console.log(` Exports: ${analysis.sizeBreakdown.exports} bytes`); console.log(` Imports: ${analysis.sizeBreakdown.imports} bytes`); console.log(` Total: ${analysis.sizeBreakdown.total} bytes`); } // Function analysis if (analysis.functions && analysis.functions.length > 0) { console.log('\nFunction analysis:'); for (const func of analysis.functions.slice(0, 5)) { console.log(` ${func.name}:`); console.log(` Size: ${func.size} bytes`); console.log(` Instructions: ${func.instructionCount}`); console.log(` Locals: ${func.localCount}`); console.log(` Exported: ${func.exported}`); console.log(` Estimated gas: ${func.estimatedGas}`); } } // Import analysis if (analysis.imports && analysis.imports.length > 0) { console.log('\nImports:'); for (const imp of analysis.imports) { console.log(` ${imp.module}.${imp.name} (${imp.kind})`); } } // Gas analysis if (analysis.gasAnalysis) { console.log('\nGas analysis:'); console.log(` Deployment: ${analysis.gasAnalysis.deploymentGas}`); console.log(` Memory init: ${analysis.gasAnalysis.memoryInitGas}`); console.log(` Data section: ${analysis.gasAnalysis.dataSectionGas}`); } // Extract metadata const metadata = await compiler.analysis.extractMetadata(wasm); console.log('\nContract metadata:'); console.log(` Name: ${metadata.name}`); console.log(` Version: ${metadata.version}`); console.log(` Build timestamp: ${metadata.buildTimestamp}`); // Estimate deployment gas const gas = await compiler.analysis.estimateDeployGas(wasm); console.log(`\nEstimated deployment gas: ${gas}`); console.log(''); } /** * Contract validation */ async function validationExample(compiler: SynorCompiler): Promise { console.log('=== Contract Validation ==='); const wasm = createMinimalWasm(); // Full validation const result = await compiler.validation.validate(wasm); console.log(`Valid: ${result.valid}`); console.log(`Exports: ${result.exportCount}`); console.log(`Imports: ${result.importCount}`); console.log(`Functions: ${result.functionCount}`); console.log(`Memory pages: ${result.memoryPages}`); if (result.errors && result.errors.length > 0) { console.log('\nValidation errors:'); for (const error of result.errors) { console.log(` [${error.code}] ${error.message}`); if (error.location) { console.log(` at ${error.location}`); } } } if (result.warnings && result.warnings.length > 0) { console.log('\nWarnings:'); for (const warning of result.warnings) { console.log(` ${warning}`); } } // Quick validation const isValid = await compiler.validation.isValid(wasm); console.log(`\nQuick validation: ${isValid}`); // Get validation errors only const errors = await compiler.validation.getErrors(wasm); console.log(`Error count: ${errors.length}`); // Validate required exports const hasRequiredExports = await compiler.validation.validateExports( wasm, ['init', 'execute', 'query'] ); console.log(`Has required exports: ${hasRequiredExports}`); // Validate memory constraints const memoryValid = await compiler.validation.validateMemory(wasm, 16); console.log(`Memory within 16 pages: ${memoryValid}`); console.log(''); } /** * Security scanning */ async function securityExample(compiler: SynorCompiler): Promise { console.log('=== Security Scanning ==='); const wasm = createMinimalWasm(); const security = await compiler.analysis.securityScan(wasm); console.log(`Security score: ${security.score}/100`); if (security.issues && security.issues.length > 0) { console.log('\nSecurity issues:'); for (const issue of security.issues) { const severityIcon = { 'critical': '🔴', 'high': '🟠', 'medium': '🟡', 'low': '🟢', }[issue.severity] || '⚪'; console.log(`${severityIcon} [${issue.severity.toUpperCase()}] ${issue.type}`); console.log(` ${issue.description}`); if (issue.location) { console.log(` at ${issue.location}`); } } } else { console.log('No security issues found!'); } if (security.recommendations && security.recommendations.length > 0) { console.log('\nRecommendations:'); for (const rec of security.recommendations) { console.log(` • ${rec}`); } } console.log(''); } /** * Create a minimal valid WASM module for testing */ function createMinimalWasm(): Buffer { // Minimal WASM module with magic number and version return Buffer.from([ 0x00, 0x61, 0x73, 0x6d, // Magic: \0asm 0x01, 0x00, 0x00, 0x00, // Version: 1 // Type section 0x01, 0x07, 0x01, 0x60, 0x02, 0x7f, 0x7f, 0x01, 0x7f, // Function section 0x03, 0x02, 0x01, 0x00, // Export section 0x07, 0x08, 0x01, 0x04, 0x61, 0x64, 0x64, 0x00, 0x00, // Code section 0x0a, 0x09, 0x01, 0x07, 0x00, 0x20, 0x00, 0x20, 0x01, 0x6a, 0x0b, ]); } // Run examples main().catch(console.error);