diff --git a/src/agents/deployer.ts b/src/agents/deployer.ts index 80e8c4f..f185ebe 100644 --- a/src/agents/deployer.ts +++ b/src/agents/deployer.ts @@ -11,6 +11,7 @@ */ import { ethers, ContractFactory, Contract, Signer, Wallet, providers } from 'ethers'; +import { logger } from '../utils/logger'; // ============================================================================ // TYPES @@ -444,14 +445,14 @@ export async function deploy( if (typeof process !== 'undefined' && process.argv[1]?.includes('deployer')) { const privateKey = process.env.DEPLOYER_PRIVATE_KEY; if (!privateKey) { - console.error('DEPLOYER_PRIVATE_KEY not set in environment'); + logger.error('DEPLOYER_PRIVATE_KEY not set in environment'); process.exit(1); } initializeDeployer(privateKey); - console.log('NoLangX Deployer initialized'); - console.log('Wallet address:', getDeployer().wallet.address); - console.log('Supported chains:', getDeployer().getSupportedChains().map(c => c.name).join(', ')); + logger.info('NoLangX Deployer initialized'); + logger.info(`Wallet address: ${getDeployer().wallet.address}`); + logger.info(`Supported chains: ${getDeployer().getSupportedChains().map(c => c.name).join(', ')}`); } export default MultiChainDeployer; diff --git a/src/agents/intentParser.ts b/src/agents/intentParser.ts index 5b605c5..529a0bd 100644 --- a/src/agents/intentParser.ts +++ b/src/agents/intentParser.ts @@ -1,6 +1,7 @@ import { ChatOpenAI } from '@langchain/openai'; import { PromptTemplate } from '@langchain/core/prompts'; import { StringOutputParser } from '@langchain/core/output_parsers'; +import { logger } from '../utils/logger'; // Contract specification interface export interface ContractSpec { @@ -326,7 +327,7 @@ class IntentParser { } if (validation.warnings.length > 0) { - console.warn('NoLangX Validation Warnings:', validation.warnings.join('; ')); + logger.warn('NoLangX Validation Warnings:', validation.warnings.join('; ')); } return spec; diff --git a/src/agents/solGenerator.ts b/src/agents/solGenerator.ts index b9b9720..9d87bd0 100644 --- a/src/agents/solGenerator.ts +++ b/src/agents/solGenerator.ts @@ -1,6 +1,7 @@ import { OpenAI } from 'openai'; import { ethers } from 'ethers'; import { IntentSpec } from './intentParser.js'; +import { logger } from '../utils/logger'; /** * NoLangX Solidity Contract Generator @@ -473,7 +474,7 @@ Return ONLY valid JSON, no markdown.`; } return params; } catch (error) { - console.error('LLM customization failed, using defaults:', error); + logger.error('LLM customization failed, using defaults:', error); return getDefaultParams(templateType, spec); } } @@ -534,7 +535,7 @@ async function estimateDeploymentGas( return gasEstimate; } catch (error) { - console.error('Gas estimation failed:', error); + logger.error('Gas estimation failed:', error); // Return reasonable default if estimation fails return BigInt(3000000); // 3M gas default for complex contracts } diff --git a/src/server.ts b/src/server.ts index c95d774..cfa73b4 100644 --- a/src/server.ts +++ b/src/server.ts @@ -1,5 +1,6 @@ import express, { Request, Response, NextFunction } from 'express'; import rateLimit from 'express-rate-limit'; +import { logger } from './utils/logger'; import { intentParser } from './agents/intentParser'; import { generateContract } from './agents/solGenerator'; import { auditContract } from './agents/auditChecker'; @@ -284,7 +285,7 @@ app.get('/api/balance', async (_req: Request, res: Response) => { }); app.use((err: Error, _req: Request, res: Response, _next: NextFunction) => { - console.error('Unhandled error:', err); + logger.error('Unhandled error:', err); res.status(500).json({ error: 'Internal server error', details: process.env.NODE_ENV === 'development' ? err.message : undefined, @@ -299,22 +300,22 @@ let server: ReturnType | null = null; function startServer(): void { server = app.listen(PORT, () => { - console.log(`NoLangX API server running on port ${PORT}`); - console.log(`Trust proxy level: ${TRUST_PROXY}`); + logger.info(`NoLangX API server running on port ${PORT}`); + logger.info(`Trust proxy level: ${TRUST_PROXY}`); }); } function gracefulShutdown(signal: string): void { - console.log(`Received ${signal}, shutting down gracefully...`); + logger.info(`Received ${signal}, shutting down gracefully...`); if (server) { server.close((err) => { if (err) { - console.error('Error during server close:', err); + logger.error('Error during server close:', err); process.exit(1); } - console.log('Server closed, all connections terminated'); + logger.info('Server closed, all connections terminated'); const handles = setInterval(() => { const activeHandles = process._getActiveHandles(); @@ -322,14 +323,14 @@ function gracefulShutdown(signal: string): void { if (activeHandles.length === 0 && activeRequests.length === 0) { clearInterval(handles); - console.log('All handles cleared, exiting process'); + logger.info('All handles cleared, exiting process'); process.exit(0); } }, 100); setTimeout(() => { clearInterval(handles); - console.log('Forced shutdown after timeout'); + logger.info('Forced shutdown after timeout'); process.exit(1); }, 10000); }); @@ -342,12 +343,12 @@ process.on('SIGTERM', () => gracefulShutdown('SIGTERM')); process.on('SIGINT', () => gracefulShutdown('SIGINT')); process.on('uncaughtException', (err) => { - console.error('Uncaught exception:', err); + logger.error('Uncaught exception:', err); gracefulShutdown('uncaughtException'); }); process.on('unhandledRejection', (reason, promise) => { - console.error('Unhandled rejection at:', promise, 'reason:', reason); + logger.error(`Unhandled rejection at: ${promise} reason: ${reason}`); gracefulShutdown('unhandledRejection'); }); diff --git a/src/utils/logger.ts b/src/utils/logger.ts new file mode 100644 index 0000000..f9e731f --- /dev/null +++ b/src/utils/logger.ts @@ -0,0 +1,35 @@ +/** + * Centralized Logger Utility + * Provides a standardized way to log messages with timestamps + */ + +class Logger { + private getTimestamp(): string { + return new Date().toISOString(); + } + + private formatMessage(level: string, message: string): string { + return `[${this.getTimestamp()}] [${level}] ${message}`; + } + + info(message: string, ...args: any[]): void { + console.log(this.formatMessage('INFO', message), ...args); + } + + warn(message: string, ...args: any[]): void { + console.warn(this.formatMessage('WARN', message), ...args); + } + + error(message: string, ...args: any[]): void { + console.error(this.formatMessage('ERROR', message), ...args); + } + + debug(message: string, ...args: any[]): void { + if (process.env.DEBUG) { + console.debug(this.formatMessage('DEBUG', message), ...args); + } + } +} + +export const logger = new Logger(); +export default logger; diff --git a/src/zk/prover.ts b/src/zk/prover.ts index 90565b7..db3916e 100644 --- a/src/zk/prover.ts +++ b/src/zk/prover.ts @@ -3,6 +3,7 @@ import { poseidon } from 'circomlibjs'; import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs'; import { join, dirname } from 'path'; import { createHash } from 'crypto'; +import { logger } from '../utils/logger'; /** * NoLangX ZK Correctness Prover @@ -265,7 +266,7 @@ export class ZKProver { : undefined }; } catch (error) { - console.error('Proof generation failed, using fallback:', error); + logger.error('Proof generation failed, using fallback:', error); return await this.fallbackProve(codeHash, properties); } } @@ -340,7 +341,7 @@ export class ZKProver { parsedProof ); } catch (error) { - console.error('Proof verification failed:', error); + logger.error('Proof verification failed:', error); return false; } }