defarm-sdk
Version:
DeFarm SDK - On-premise blockchain data processing and tokenization engine for agriculture supply chain
510 lines (422 loc) • 13.8 kB
JavaScript
const { createModule } = require('../module-system');
/**
* Agriculture Module for DeFarm SDK
* Handles agriculture-specific data processing, validation, and tokenization
*/
// Asset types supported
const ASSET_TYPES = {
LIVESTOCK: 'livestock',
CROP: 'crop',
LAND: 'land',
EQUIPMENT: 'equipment',
PRODUCE: 'produce',
SEED: 'seed',
FERTILIZER: 'fertilizer',
WATER_RIGHTS: 'water_rights'
};
// Event types for supply chain tracking
const EVENT_TYPES = {
PLANTING: 'planting',
HARVESTING: 'harvesting',
PROCESSING: 'processing',
PACKAGING: 'packaging',
STORAGE: 'storage',
TRANSPORT: 'transport',
QUALITY_CHECK: 'quality_check',
CERTIFICATION: 'certification',
SALE: 'sale',
OWNERSHIP_TRANSFER: 'ownership_transfer'
};
// Certification types
const CERTIFICATION_TYPES = {
ORGANIC: 'organic',
FAIR_TRADE: 'fair_trade',
RAINFOREST_ALLIANCE: 'rainforest_alliance',
GAP: 'good_agricultural_practices',
ISO_22000: 'iso_22000',
HACCP: 'haccp',
SUSTAINABLE: 'sustainable',
CARBON_NEUTRAL: 'carbon_neutral'
};
// Validation rules for agriculture data
const validationRules = {
livestock: {
required: ['breed', 'age', 'weight', 'health_status'],
optional: ['vaccination_records', 'feed_type', 'location_history']
},
crop: {
required: ['crop_type', 'variety', 'planting_date', 'area_hectares'],
optional: ['expected_yield', 'irrigation_method', 'pesticide_use', 'fertilizer_use']
},
land: {
required: ['location', 'area_hectares', 'soil_type', 'ownership_type'],
optional: ['water_source', 'elevation', 'slope', 'previous_crops']
},
produce: {
required: ['product_type', 'quantity', 'unit', 'harvest_date'],
optional: ['grade', 'storage_conditions', 'shelf_life', 'batch_number']
}
};
// Processors for different asset types
const processors = {
livestock: {
process: async (data, options = {}) => {
// Validate livestock-specific data
const validation = validateLivestockData(data);
if (!validation.valid) {
throw new Error(`Livestock validation failed: ${validation.errors.join(', ')}`);
}
// Calculate health score
data.health_score = calculateHealthScore(data);
// Generate unique livestock ID
if (!data.livestock_id) {
data.livestock_id = generateLivestockId(data);
}
// Add traceability metadata
data.traceability = {
origin: data.origin || 'unknown',
current_location: data.location,
movement_history: data.movement_history || [],
ownership_history: data.ownership_history || []
};
// Calculate carbon footprint
if (options.calculateCarbon) {
data.carbon_footprint = calculateLivestockCarbonFootprint(data);
}
return data;
}
},
crop: {
process: async (data, options = {}) => {
// Validate crop-specific data
const validation = validateCropData(data);
if (!validation.valid) {
throw new Error(`Crop validation failed: ${validation.errors.join(', ')}`);
}
// Calculate expected yield
if (!data.expected_yield) {
data.expected_yield = calculateExpectedYield(data);
}
// Add sustainability metrics
data.sustainability = {
water_usage: calculateWaterUsage(data),
pesticide_index: calculatePesticideIndex(data),
soil_health: data.soil_health || 'good',
biodiversity_score: data.biodiversity_score || 0.7
};
// Calculate carbon sequestration
if (options.calculateCarbon) {
data.carbon_sequestration = calculateCropCarbonSequestration(data);
}
return data;
}
},
produce: {
process: async (data, options = {}) => {
// Validate produce data
const validation = validateProduceData(data);
if (!validation.valid) {
throw new Error(`Produce validation failed: ${validation.errors.join(', ')}`);
}
// Calculate quality score
data.quality_score = calculateQualityScore(data);
// Add shelf life information
if (!data.shelf_life) {
data.shelf_life = estimateShelfLife(data);
}
// Add market value estimation
if (options.estimateValue) {
data.estimated_value = await estimateMarketValue(data);
}
return data;
}
}
};
// Validators for agriculture fields
const validators = {
location: (value) => {
if (!value || typeof value !== 'object') return false;
if (!value.latitude || !value.longitude) return false;
const lat = parseFloat(value.latitude);
const lon = parseFloat(value.longitude);
return lat >= -90 && lat <= 90 && lon >= -180 && lon <= 180;
},
harvest_date: (value) => {
const date = new Date(value);
return !isNaN(date.getTime()) && date <= new Date();
},
quantity: (value) => {
return typeof value === 'number' && value > 0;
},
certification: (value) => {
if (!value || typeof value !== 'object') return false;
return value.type && value.issuer && value.valid_until;
},
soil_type: (value) => {
const validTypes = ['clay', 'sandy', 'loamy', 'silt', 'peat', 'chalk'];
return validTypes.includes(value.toLowerCase());
}
};
// Hooks for agriculture processing
const hooks = {
'validate:agriculture': async (data) => {
// General agriculture validation
if (!data.asset_type || !ASSET_TYPES[data.asset_type.toUpperCase()]) {
throw new Error(`Invalid asset type: ${data.asset_type}`);
}
// Check required fields based on asset type
const rules = validationRules[data.asset_type];
if (rules) {
for (const field of rules.required) {
if (!data[field]) {
throw new Error(`Required field missing: ${field}`);
}
}
}
return data;
},
'pre:tokenization': async (data) => {
// Prepare data for tokenization
if (data.asset_type === ASSET_TYPES.LIVESTOCK) {
data.token_metadata = {
breed: data.breed,
age: data.age,
health_score: data.health_score,
certifications: data.certifications || []
};
} else if (data.asset_type === ASSET_TYPES.CROP) {
data.token_metadata = {
crop_type: data.crop_type,
variety: data.variety,
area: data.area_hectares,
expected_yield: data.expected_yield,
sustainability: data.sustainability
};
}
return data;
},
'post:blockchain': async (data) => {
// After blockchain recording, update local records
console.log(`Agriculture asset recorded on blockchain: ${data.blockchainTx}`);
// Add blockchain verification flag
data.blockchain_verified = true;
data.verification_timestamp = Date.now();
return data;
},
'compliance:check': async (data) => {
const results = {
organic: false,
sustainable: false,
fair_trade: false,
carbon_neutral: false
};
// Check organic compliance
if (data.criteria.includes('organic')) {
results.organic = checkOrganicCompliance(data.options);
}
// Check sustainability
if (data.criteria.includes('sustainable')) {
results.sustainable = checkSustainabilityCompliance(data.options);
}
return results;
}
};
// Helper functions
function validateLivestockData(data) {
const errors = [];
if (!data.breed) errors.push('Breed is required');
if (!data.age || data.age < 0) errors.push('Valid age is required');
if (!data.weight || data.weight <= 0) errors.push('Valid weight is required');
if (!data.health_status) errors.push('Health status is required');
return {
valid: errors.length === 0,
errors
};
}
function validateCropData(data) {
const errors = [];
if (!data.crop_type) errors.push('Crop type is required');
if (!data.planting_date) errors.push('Planting date is required');
if (!data.area_hectares || data.area_hectares <= 0) {
errors.push('Valid area in hectares is required');
}
return {
valid: errors.length === 0,
errors
};
}
function validateProduceData(data) {
const errors = [];
if (!data.product_type) errors.push('Product type is required');
if (!data.quantity || data.quantity <= 0) errors.push('Valid quantity is required');
if (!data.unit) errors.push('Unit is required');
if (!data.harvest_date) errors.push('Harvest date is required');
return {
valid: errors.length === 0,
errors
};
}
function calculateHealthScore(data) {
let score = 100;
// Deduct points for health issues
if (data.health_issues && data.health_issues.length > 0) {
score -= data.health_issues.length * 10;
}
// Bonus for complete vaccination records
if (data.vaccination_records && data.vaccination_records.length > 0) {
score += 5;
}
// Consider age factor
if (data.age > 10) {
score -= 5;
}
return Math.max(0, Math.min(100, score));
}
function generateLivestockId(data) {
const crypto = require('crypto');
const input = `${data.breed}-${data.tag_number || ''}-${Date.now()}`;
const hash = crypto.createHash('sha256').update(input).digest('hex');
return `LIVESTOCK-${hash.substring(0, 12).toUpperCase()}`;
}
function calculateExpectedYield(data) {
// Simple yield calculation based on crop type and area
const yieldPerHectare = {
wheat: 3.5,
corn: 10.5,
rice: 4.5,
soybean: 3.0,
potato: 45.0
};
const baseYield = yieldPerHectare[data.crop_type] || 5.0;
return baseYield * data.area_hectares;
}
function calculateWaterUsage(data) {
// Liters per hectare per season
const waterRequirements = {
wheat: 4500000,
corn: 5500000,
rice: 15000000,
soybean: 4500000,
potato: 5000000
};
const baseUsage = waterRequirements[data.crop_type] || 5000000;
const efficiency = data.irrigation_method === 'drip' ? 0.7 : 1.0;
return baseUsage * data.area_hectares * efficiency;
}
function calculatePesticideIndex(data) {
if (!data.pesticide_use) return 0;
// Simple index based on pesticide usage
const usage = data.pesticide_use.toLowerCase();
if (usage === 'none' || usage === 'organic') return 0;
if (usage === 'minimal') return 0.3;
if (usage === 'moderate') return 0.6;
if (usage === 'high') return 0.9;
return 0.5; // default
}
function calculateLivestockCarbonFootprint(data) {
// CO2 equivalent per year
const emissionFactors = {
cattle: 2500,
sheep: 300,
goat: 250,
pig: 450,
chicken: 10
};
const factor = emissionFactors[data.breed] || 500;
const ageMultiplier = Math.min(data.age, 5); // Cap at 5 years
return factor * ageMultiplier;
}
function calculateCropCarbonSequestration(data) {
// CO2 sequestration per hectare per year
const sequestrationRates = {
wheat: 1.5,
corn: 2.0,
rice: 0.5,
soybean: 1.8,
forest: 10.0
};
const rate = sequestrationRates[data.crop_type] || 1.0;
return rate * data.area_hectares;
}
function calculateQualityScore(data) {
let score = 80; // Base score
if (data.grade === 'A' || data.grade === 'Premium') score += 20;
else if (data.grade === 'B') score += 10;
// Freshness factor
const daysSinceHarvest = Math.floor((Date.now() - new Date(data.harvest_date)) / (1000 * 60 * 60 * 24));
score -= Math.min(daysSinceHarvest * 2, 30);
return Math.max(0, Math.min(100, score));
}
function estimateShelfLife(data) {
const shelfLifeDays = {
tomato: 7,
potato: 30,
onion: 60,
carrot: 21,
lettuce: 5,
apple: 30,
banana: 7,
grain: 365
};
return shelfLifeDays[data.product_type] || 14;
}
async function estimateMarketValue(data) {
// This would normally fetch real market prices
// For now, return a mock calculation
const pricePerUnit = {
tomato: 2.5,
potato: 1.5,
onion: 1.8,
carrot: 2.0,
wheat: 250, // per ton
corn: 200, // per ton
rice: 400 // per ton
};
const basePrice = pricePerUnit[data.product_type] || 100;
const qualityMultiplier = (data.quality_score || 80) / 100;
return {
currency: 'USD',
amount: basePrice * data.quantity * qualityMultiplier,
timestamp: Date.now()
};
}
function checkOrganicCompliance(options) {
// Check for organic certification
if (!options.certifications) return false;
return options.certifications.some(cert =>
cert.type === CERTIFICATION_TYPES.ORGANIC &&
new Date(cert.valid_until) > new Date()
);
}
function checkSustainabilityCompliance(options) {
// Check sustainability metrics
if (!options.sustainability) return false;
const s = options.sustainability;
return s.water_usage < 10000000 && // Less than 10M liters per hectare
s.pesticide_index < 0.3 &&
s.biodiversity_score > 0.6;
}
// Create and export the module
module.exports = createModule('agriculture')
.version('1.0.0')
.description('Agriculture data processing and validation for DeFarm SDK')
// Register processors
.processor('livestock', processors.livestock)
.processor('crop', processors.crop)
.processor('produce', processors.produce)
// Register validators
.validator('location', validators.location)
.validator('harvest_date', validators.harvest_date)
.validator('quantity', validators.quantity)
.validator('certification', validators.certification)
.validator('soil_type', validators.soil_type)
// Register hooks
.hook('validate:agriculture', hooks['validate:agriculture'])
.hook('pre:tokenization', hooks['pre:tokenization'])
.hook('post:blockchain', hooks['post:blockchain'])
.hook('compliance:check', hooks['compliance:check'])
.build();
// Export constants for external use
module.exports.ASSET_TYPES = ASSET_TYPES;
module.exports.EVENT_TYPES = EVENT_TYPES;
module.exports.CERTIFICATION_TYPES = CERTIFICATION_TYPES;