/** * Blockchain Manager * Singleton to manage the global plant blockchain instance */ import { PlantChain } from './PlantChain'; import fs from 'fs'; import path from 'path'; const BLOCKCHAIN_FILE = path.join(process.cwd(), 'data', 'plantchain.json'); class BlockchainManager { private static instance: BlockchainManager; private plantChain: PlantChain; private autoSaveInterval: NodeJS.Timeout | null = null; private constructor() { this.plantChain = this.loadBlockchain(); this.startAutoSave(); } public static getInstance(): BlockchainManager { if (!BlockchainManager.instance) { BlockchainManager.instance = new BlockchainManager(); } return BlockchainManager.instance; } public getChain(): PlantChain { return this.plantChain; } /** * Load blockchain from file or create new one */ private loadBlockchain(): PlantChain { try { // Ensure data directory exists const dataDir = path.join(process.cwd(), 'data'); if (!fs.existsSync(dataDir)) { fs.mkdirSync(dataDir, { recursive: true }); } if (fs.existsSync(BLOCKCHAIN_FILE)) { const data = fs.readFileSync(BLOCKCHAIN_FILE, 'utf-8'); const chainData = JSON.parse(data); console.log('✓ Loaded existing blockchain with', chainData.chain.length, 'blocks'); return PlantChain.fromJSON(chainData); } } catch (error) { console.error('Error loading blockchain:', error); } console.log('✓ Created new blockchain'); return new PlantChain(4); // difficulty of 4 } /** * Save blockchain to file */ public saveBlockchain(): void { try { const dataDir = path.join(process.cwd(), 'data'); if (!fs.existsSync(dataDir)) { fs.mkdirSync(dataDir, { recursive: true }); } const data = JSON.stringify(this.plantChain.toJSON(), null, 2); fs.writeFileSync(BLOCKCHAIN_FILE, data, 'utf-8'); console.log('✓ Blockchain saved'); } catch (error) { console.error('Error saving blockchain:', error); } } /** * Auto-save blockchain every 5 minutes */ private startAutoSave(): void { if (this.autoSaveInterval) { clearInterval(this.autoSaveInterval); } this.autoSaveInterval = setInterval(() => { this.saveBlockchain(); }, 5 * 60 * 1000); // 5 minutes } /** * Stop auto-save */ public stopAutoSave(): void { if (this.autoSaveInterval) { clearInterval(this.autoSaveInterval); this.autoSaveInterval = null; } } } export function getBlockchain(): PlantChain { return BlockchainManager.getInstance().getChain(); } export function saveBlockchain(): void { BlockchainManager.getInstance().saveBlockchain(); }