jamkernel/jamkernelp2p
JAM Omni-Kernel — Zero-dependency P2P mesh. Single file. Cross-platform. Sitio web: - jamkernel/jamkernelp2p
1 stars · 0 forks · JavaScript Topics: mesh-networks, webrtc, p2p, mesh, mesh-generation, webrtc-javascript-library, webrtc-experiments, p2p-node, webrtc-call, webrtc-demo, webrtc-libraries, p2p-chat, webrtc-signaling, p2p-network, mesh-network, meshtastic, mesh-networking-suru-zekasi
README
jamkernelp2p v1.2.0 José Alejandro Martínez Base mínima · Arquitectura pura · Cero dependencias ¿Qué es? · Arquitectura · Versiones · Quick Start · API · Roadmap v2.1.0 · Licencia GitHub · Contacto node jamkernelp2p.js --room mi-sala --password clave-segura
¿Qué es? jamkernelp2p es un kernel de comunicación P2P en un solo archivo (~2.900 líneas) que funciona en navegadores, Node.js, Deno y Bun sin ninguna dependencia externa. Creado por Félix Martínez y dedicado a su hijo José Alejandro Martínez. No es un wrapper de WebRTC ni una adaptación de libp2p. Es una arquitectura original de microkernel P2P con capas de plataforma, identidad criptográfica, cifrado, transporte mesh y señalización embebida — todo en un solo archivo autocontenido. Filosofía
"La verdadera descentralización no es un protocolo. Es la capacidad de cualquier persona, en cualquier lugar, con cualquier dispositivo, de comunicarse sin pedir permiso."
Arquitectura ┌──────────────────────────────────────────────────────────────┐ │ JAMKernelP2P (Orquestador) │ ├─────────────┬──────────────┬──────────────┬──────────────────┤ │ Identity │ Mesh │ Crypto │ Persistence │ │ (ECDSA │ (SecureJam │ (AES-256 │ (BatchStorage │ │ P-256) │ Mesh Adap) │ GCM + │ + estado) │ │ │ │ PBKDF2) │ │ ├─────────────┴──────────────┴──────────────┴──────────────────┤ │ Capa de Transporte │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ Browser │ │ Node.js │ │ Deno │ │ Bun │ │ │ │ (WebRTC) │ │(WebSocket│ │(WebSocket│ │(WebSocket│ │ │ │ │ │ +Relay) │ │ +Relay) │ │ +Relay) │ │ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ ├──────────────────────────────────────────────────────────────┤ │ MiniSignalServer (embebido, RFC 6455) │ │ WebSocket signaling + mesh relay + auth + rate limit │ └──────────────────────────────────────────────────────────────┘
Cada capa es independiente. Puedes reemplazar el MiniSignalServer por un relay externo sin tocar el mesh, la identidad, ni el cifrado. Componentes del Kernel
Clase Función
IPlatform / adapters Abstracción multiplataforma (Browser, Node, Deno, Bun)
EventBus Sistema de eventos asíncrono, desacopla componentes
JamCrypto AES-256-GCM + PBKDF2(600K) + ECDSA P-256 + ECDH forward secrecy
IdentityManager Claves ECDSA, peerId = SHA-256(publicKey)
MiniSignalServer Signaling WebSocket RFC 6455 zero-deps
SecureJamMeshAdapter Mesh P2P con WebRTC + relay + ACKs + ratchet + LAN discovery + anti-replay + heartbeat
BatchStorage Persistencia (IndexedDB / archivo JSON)
WorkerPool Cola de tareas con concurrencia limitada
PluginManager Sistema de plugins extensible
StructuredLogger Logging con niveles y rotación
Lo que hace ahora (v1.2.0)
0 dependencias externas — solo APIs nativas de cada plataforma WebSocket RFC 6455 propio — servidor + cliente + framing desde cero Cifrado real — AES-256-GCM + PBKDF2(600K) + ECDSA P-256 Forward secrecy (ECDH + ratchet) — Intercambio de claves efímeras P-256 + ratchet que avanza por mensaje LAN Discovery — Descubrimiento de peers en red local vía UDP broadcast (0 dependencias) Anti-replay — Ventana deslizante de 64 secuencias evita reinyección de paquetes Heartbeat — Keepalive cada 30s al servidor de señalización Mesh P2P — WebRTC browser-to-browser; relay WebSocket en Node.js Servidor de señalización embebido — arranca con --port Anti-DoS — rate limiting 60 msg/s + blacklist automática ACKs con reintentos — entrega confirmada (hasta 2 reintentos) CLI completo — --port --room --password --tls-key --tls-cert --log-file --log-level --help Multiplataforma — browser, Node.js, Deno, Bun Persistencia de identidad — ECDSA se guarda automáticamente Plugins — sistema de extensiones vía JAMPlugin
Lo que viene: v2.1.0 (próximamente)
Lanzamiento en las próximas semanas. Esta versión eleva el kernel a capacidades de producción con nuevas funcionalidades y pulido profesional.
Mejora Estado
Omni-Kernel branding Nombre unificado: JAM Omni-Kernel
Autenticación por token --token para salas con acceso restringido
Cluster mode real Distribución de peers entre workers vía IPC
Canales virtuales API unificada WebRTC DataChannel + WebSocket relay
Purga forense mejorada Sobrescritura de claves en RAM al cerrar sesión
Idle timeout Desconexión automática por inactividad (5 min)
Límite de payload 256KB máximo por mensaje
Reconexión automática Reintento periódico al signal server
Documentación completa Manual, plugins, troubleshooting
Versiones disponibles
Versión Archivo Tamaño Descripción Descarga
v1.0 jamkernelp2p-v1.0.js 84 KB Kernel original simple: AES-256 + ECDSA + WebSocket propio + mesh básico Descargar
v1.2.0 jamkernelp2p.js 115 KB Kernel actual: + ECDH forward secrecy + ratchet + LAN discovery + heartbeat + anti-replay + 19 bugs corregidos Descargar
v2.1.0 — — Próxima versión: token auth, cluster mode real, canales virtuales, purga forense mejorada Roadmap abajo
¿Cuál usar?
v1.0 — Ideal para aprendizaje, auditoría de código, o sistemas embebidos donde cada KB importa. Menos features, más simple de leer. v1.2.0 — Producción. Toda la seguridad (forward secrecy, anti-replay), descubrimiento LAN, heartbeat, y 19 bugs corregidos respecto a v1.0. v2.1.0 — Cuando esté lista: autenticación por token, cluster real, canales virtuales unificados.
Diferencias clave v1.0 → v1.2.0
Aspecto v1.0 v1.2.0
Líneas ~2.200 ~2.900
PBKDF2 iteraciones 60.000 600.000
Rate limit 12 msg/s 60 msg/s
Forward secrecy (ECDH) ❌ ✅
Ratchet de claves ❌ ✅
LAN Discovery (UDP) ❌ ✅
Heartbeat / keepalive ❌ ✅
Anti-replay (ventana 64) ❌ ✅
Bugs conocidos Varios 19 corregidos
TLS con fallback HTTP ❌ ✅
CLI con validación Parcial Completa
Instalación No necesitas npm install. Este proyecto tiene cero dependencias. Solo descarga el archivo que quieras y ejecútalo:
v1.2.0 (actual)
curl -O https://raw.githubusercontent.com/jamkernel/jamkernelp2p/main/jamkernelp2p.js node jamkernelp2p.js --room mi-sala --password clave-segurav1.0 (kernel original)
curl -O https://raw.githubusercontent.com/jamkernel/jamkernelp2p/main/jamkernelp2p-v1.0.js node jamkernelp2p-v1.0.js --room mi-sala --password clave-seguraClonar el repo completo
git clone https://github.com/jamkernel/jamkernelp2p.git cd jamkernelp2p node jamkernelp2p.js --room mi-sala --password clave-segura El package.json incluido es solo para metadatos — no hay dependencias que instalar. Quick StartPeer + servidor de señalización + mesh (todo en uno)
node jamkernelp2p.js --room mi-sala --password clave-seguraCon puerto específico
node jamkernelp2p.js --port 9090 --room privado --password claveTLS para producción
node jamkernelp2p.js --tls-key cert.pem --tls-cert cert.pem --port 443Logging
node jamkernelp2p.js --log-file jam.log --log-level info --room test --password 12345678Ayuda
node jamkernelp2p.js --help Opciones CLIFlag Default Descripción
--port N 0 (aleatorio) Puerto del servidor de señalización
--room X — Sala a la que unirse
--password X — Contraseña de cifrado (mín. 8 caracteres)
--tls-key FILE — Clave TLS para WSS
--tls-cert FILE — Certificado TLS para WSS
--log-file FILE — Archivo de log (JSON lines)
--log-level L warn error, warn, info, debug
--host H 0.0.0.0 Host del servidor
--help, -h — Muestra ayuda
API const { JAMOmni } = require('./jamkernelp2p.js');
// Creación auto-configurada const kernel = await JAMOmni.createKernel({});
// Esperar a que la identidad esté lista const peerId = await kernel.whenIdentityReady(); console.log('Peer ID:', peerId);
// Escuchar mensajes kernel.events.on('peer:message', ({ peerId, message }) => { console.log(`${peerId}:`, message); });
// Unirse a una sala cifrada await kernel.startSession('mi-sala', 'mi-clave');
// Transmitir a todos await kernel.broadcast({ text: 'Hola mundo P2P!' });
// Enviar a un peer específico await kernel.sendTo(peerId, { text: 'Mensaje directo' });
// Cerrar sesión (purga de claves) await kernel.closeSession(); Plugins const { JAMPlugin } = require('./jamkernelp2p.js');
class MiPlugin extends JAMPlugin { async init(config) { this.events.on('peer:message', (msg) => { this.log.info('Plugin:', msg); }); } }
kernel.registerPlugin('mi-plugin', MiPlugin); await kernel.loadPlugin('mi-plugin', { opcion: 'valor' });
Uso en otras plataformas Navegador (Browser) <script src="jamkernelp2p.js"></script> <script> (async () => { const kernel = await window.JAM.Omni.createKernel({ signalUrl: 'ws://servidor:puerto' });
const peerId = await kernel.whenIdentityReady(); console.log('Peer ID:', peerId);
kernel.events.on('peer:message', ({ peerId, message }) => { console.log(`${peerId}:`, message); });
await kernel.startSession('mi-sala', 'mi-clave'); await kernel.broadcast({ text: 'Hola desde el navegador!' }); })(); </script> Deno // deno run --allow-net --allow-write --allow-read jamkernelp2p.js import { JAMOmni } from './jamkernelp2p.js';
const kernel = await JAMOmni.createKernel({ room: 'mi-sala', password: 'clave-segura' });
const peerId = await kernel.whenIdentityReady(); console.log('Peer ID:', peerId); Bun bun jamkernelp2p.js --room mi-sala --password clave-segura // Uso programático en Bun import { JAMOmni } from './jamkernelp2p.js';
const kernel = await JAMOmni.createKernel({ room: 'mi-sala', password: 'clave-segura' });
Comparativa vs Ecosistema
Característica jamkernelp2p libp2p PeerJS simple-peer
Archivos 1 100+ 5+ 3+
Dependencias 0 50+ 10+ 5+
Browser + Node.js ✅ ✅ ✅ ✅
Deno + Bun ✅ ❌ ❌ ❌
Señalización embebida ✅ ❌ ❌ ❌
Identidad ECDSA nativa ✅ Opcional ❌ ❌
Forward secrecy (ECDH + ratchet) ✅ Opcional ❌ ❌
LAN Discovery (UDP) ✅ ❌ ❌ ❌
Anti-replay ✅ ❌ ❌ ❌
Heartbeat / keepalive ✅ ❌ ❌ ❌
TLS nativo (WSS) ✅ ❌ ❌ ❌
Logging estructurado ✅ ❌ ❌ ❌
ACKs de entrega ✅ Opcional ❌ ❌
Rate limiting anti-DoS ✅ Plugin ❌ ❌
Persistencia de estado ✅ ❌ ❌ ❌
Plugins ✅ ✅ ❌ ❌
Zero-config CLI ✅ ❌ ❌ ❌
Problemas Comunes El peer no conecta al servidor de señalización Verificar puerto abierto y firewall. El servidor muestra el puerto en consola al arrancar. "Firma inválida" en announce La identidad ECDSA no coincide con la clave pública enviada. O el peer fue comprometido o hay un error de clave. Limpiar mesh._peerPublicKeys si es falso positivo. Rate limiting activado 60 msg/s por peer. Si es falso positivo (ej. transferencia rápida de datos), ajustar: kernel.mesh.MAX_MESSAGES_PER_SECOND = 120; La identidad se pierde al recargar el navegador La identidad se persiste en BatchStorage. Si el usuario borra datos del sitio, genera una nueva. Para persistencia forzada, exportar con identity.toJSON() y guardar en localStorage.
Contacto y Comunidad
Canal Enlace
📩 Correo jamkernelp2p@gmail.com
🐙 GitHub https://github.com/jamkernel/jamkernelp2p
✈️ Telegram (contacto) https://t.me/jamkernelp2p
📢 Canal Telegram https://t.me/boost/jamkernelp2p_proyecto
🌐 Sitio Web https://jamkernel.github.io
Licencia GNU GPL v3 — Eres libre de usar, modificar y distribuir este software bajo los términos de GNU GPL v3. Para uso en productos propietarios, contactar a jamkernelp2p@gmail.com.
Creado por Félix Martínez · 2026 Dedicado a José Alejandro Martínez — motor e inspiración ❤️