/** * Cryptographic Utilities * * Hash functions for content deduplication and verification. */ import { createHash } from 'crypto'; /** * Generate SHA-256 hash of content */ export function sha256(content) { if (typeof content !== 'string') { content = JSON.stringify(content); } return createHash('sha256').update(content).digest('hex'); } /** * Generate content hash for metadata comparison * Excludes volatile fields like server_time */ export function hashMetadata(metadata) { if (!metadata) return null; // Extract stable fields only const stableFields = { name: metadata.name, pubkey: metadata.pubkey, version: metadata.version, description: metadata.description, description_long: metadata.description_long, contact: metadata.contact, motd: metadata.motd, icon_url: metadata.icon_url, nuts: metadata.nuts, tos_url: metadata.tos_url, }; // Sort keys for consistent hashing const sorted = JSON.stringify(stableFields, Object.keys(stableFields).sort()); return sha256(sorted); } /** * Generate a short hash for display */ export function shortHash(content, length = 8) { return sha256(content).substring(0, length); }