JosΓ© Alejandro MartΓnez
Base mΓnima Β· Arquitectura pura Β· Cero dependencias
ΒΏQuΓ© es? Β· Arquitectura Β· Quick Start Β· API Β· Roadmap v2.1.0 Β· Licencia
node jamkernelp2p.js --room mi-sala --password clave-segura
jamkernelp2p es un kernel de comunicaciΓ³n P2P en un solo archivo (~2.200 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.
"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."
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 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.
| 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(60K) + ECDSA P-256 |
IdentityManager |
Claves ECDSA, peerId = SHA-256(publicKey) |
MiniSignalServer |
Signaling WebSocket RFC 6455 zero-deps |
SecureJamMeshAdapter |
Mesh P2P con WebRTC + relay + ACKs + rate limiting |
BatchStorage |
Persistencia (IndexedDB / archivo JSON) |
WorkerPool |
Cola de tareas con concurrencia limitada |
PluginManager |
Sistema de plugins extensible |
StructuredLogger |
Logging con niveles y rotaciΓ³n |
- 0 dependencias externas β solo APIs nativas de cada plataforma
- WebSocket RFC 6455 propio β servidor + cliente + framing desde cero
- Cifrado real β AES-256-GCM + PBKDF2(60K) + ECDSA P-256
- 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
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 |
No necesitas npm install. Este proyecto tiene cero dependencias. Solo descarga el archivo y ejecΓΊtalo:
# OpciΓ³n 1: Desde GitHub (sin clonar)
curl -O https://raw.githubusercontent.com/jamkernel/jamkernelp2p/main/jamkernelp2p.js
node jamkernelp2p.js --room mi-sala --password clave-segura
# OpciΓ³n 2: Clonar el repo
git clone https://github.com/jamkernel/jamkernelp2p.git
cd jamkernelp2p
node jamkernelp2p.js --room mi-sala --password clave-seguraEl package.json incluido es solo para metadatos β no hay dependencias que instalar.
# Peer + servidor de seΓ±alizaciΓ³n + mesh (todo en uno)
node jamkernelp2p.js --room mi-sala --password clave-segura
# Con puerto especΓfico
node jamkernelp2p.js --port 9090 --room privado --password clave
# TLS para producciΓ³n
node jamkernelp2p.js --tls-key cert.pem --tls-cert cert.pem --port 443
# Logging
node jamkernelp2p.js --log-file jam.log --log-level info --room test --password 12345678
# Ayuda
node jamkernelp2p.js --help| Flag | 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 |
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();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' });<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 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 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'
});| 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 | β | β |
| TLS nativo (WSS) | β | β | β | β |
| Logging estructurado | β | β | β | β |
| ACKs de entrega | β | Opcional | β | β |
| Rate limiting anti-DoS | β | Plugin | β | β |
| Persistencia de estado | β | β | β | β |
| Plugins | β | β | β | β |
| Zero-config CLI | β | β | β | β |
Verificar puerto abierto y firewall. El servidor muestra el puerto en consola al arrancar.
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.
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 persiste en BatchStorage. Si el usuario borra datos del sitio, genera una nueva. Para persistencia forzada, exportar con identity.toJSON() y guardar en localStorage.
| Canal | Enlace |
|---|---|
| π© Correo | jamkernelp2p@gmail.com |
| π GitHub | https://github.com/jamkernel/jamkernelp2p |
| https://t.me/jamkernelp2p | |
| π’ Canal Telegram | https://t.me/boost/jamkernelp2p_proyecto |
| π Sitio Web | https://jamkernel.github.io |
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.
Dedicado a JosΓ© Alejandro MartΓnez β motor e inspiraciΓ³n β€οΈ