localgreenchain/lib/blockchain/manager.ts
Claude 1e14a700c7
Implement LocalGreenChain: Plant Cloning Blockchain System
This commit implements a complete blockchain-based plant tracking system
that preserves lineage across clones, seeds, and all plant offspring while
connecting growers through geographic proximity.

Features implemented:
- Custom blockchain with proof-of-work consensus
- Plant registration and cloning with lineage tracking
- Geographic discovery to find nearby plants and growers
- Integration with plants.net API for plant identification
- Comprehensive web UI for plant management
- RESTful API endpoints for all operations
- Network statistics and visualization

Core Components:
- lib/blockchain/: PlantBlock, PlantChain, and blockchain manager
- lib/services/: plants.net API and geolocation services
- pages/api/plants/: REST API endpoints for all operations
- pages/: Frontend UI pages for registration, exploration, and lineage

Technical Details:
- TypeScript for type safety
- Next.js for server-side rendering
- Tailwind CSS for responsive design
- JSON file-based blockchain storage
- Haversine distance calculations for geolocation
- OpenStreetMap integration for geocoding

This system enables large-scale adoption by:
- Making plant lineage tracking accessible to everyone
- Connecting local communities through plant sharing
- Providing immutable proof of plant provenance
- Supporting unlimited generations of plant propagation
- Scaling from individual growers to global networks

Documentation includes comprehensive README with:
- Quick start guide
- API reference
- Architecture details
- Scaling recommendations
- Use cases for various audiences
- Roadmap for future enhancements
2025-11-16 05:11:55 +00:00

106 lines
2.7 KiB
TypeScript

/**
* 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();
}