Nostr Compass #23
Primal 3.5 estrena un shell de Android reconstruido, Amethyst añade zaps de Bitcoin en cadena, White Noise gana renderizado de markdown y enlaces profundos, Keycast pasa una auditoría de seguridad y AgentNoise te permite controlar agentes de codificación de IA locales sobre chat cifrado con Marmot. Hostr lanza una plataforma P2P de alojamiento en alquiler sobre Nostr con cuatro borradores de NIP que cubren listados, reservas y escrow basado en EVM. Angor migra la mensajería cifrada de NIP-04 a NIP-44, Dart NDK añade NIP-77 y un firmador web, Alby js-sdk v8 estrena reconexión multi-relay nativa para NWC y KeyChat parchea una brecha de secreto hacia adelante en la eliminación de prekeys únicas de Signal. En el lado del protocolo, el bono anti-abuso de Mostro alcanza la Fase 2, Wisp estrena respuestas privadas y reacciones envueltas en gift wrap, y una ola de implementación de NIP-05 sobre Namecoin toca media docena de clientes en una sola semana.
Historias principales
Primal 3.5 para Android
Primal, el cliente social respaldado por su propia infraestructura de relay de caché, publicó 3.5.9 esta semana con un shell de aplicación reconstruido. El rediseño reemplaza la estructura de navegación anterior por un diseño actualizado y una nueva pantalla Explore, dando a la superficie principal de descubrimiento su propio hogar dedicado. El lanzamiento añade reproducción de audio para las vistas previas de enlaces, para que los archivos de audio incrustados en las notas se reproduzcan en línea sin salir del feed. Las insignias de verificación NIP-05 ahora se muestran en línea en los perfiles, exponiendo la confirmación de identidad de un vistazo. El filtrado de notificaciones recibió una revisión, permitiendo a los usuarios acotar qué tipos de eventos llegan a su lista de notificaciones. El editor ganó un mejor manejo de enlaces a eventos, y la capa de base de datos subyacente recibió correcciones de estabilidad.
White Noise: markdown, enlaces profundos y metadatos de audio
White Noise, la app de mensajería de grupo cifrada con Marmot construida sobre Nostr y MLS (RFC 9420), tuvo una de sus semanas más ocupadas hasta la fecha en los repositorios frontend y backend.
En el frontend, PR #665 añade renderizado completo de markdown para los mensajes de chat, por lo que negrita, cursiva, bloques de código y enlaces ahora se renderizan de forma nativa en la vista de mensajes. PR #675 habilita el flujo para abandonar el grupo que anteriormente estaba bloqueado para administradores no-último, y PR #661 añade soporte nativo de enlaces profundos para los URIs whitenoise:// y whitenoise-staging:// cubriendo usuarios, chats y ajustes, sin requerir ninguna infraestructura de redirección HTTP.
En el backend en whitenoise-rs, PR #835 hace que la rotación de key packages funcione correctamente reutilizando la ranura d_tag para publicaciones kind:30443, habilitando la semántica de evento reemplazable NIP-33 para que las rotaciones sucesivas de key packages reemplacen al evento anterior en los relays, manteniendo solo el key package actual. PR #833 extiende FileMetadata con campos opcionales duration_ms y waveform para adjuntos de audio, coordinado con PR #300 de MDK que añade los mismos campos a los tags de medios MIP-04. Un nuevo crate whitenoise-markdown (PR #836) reemplaza el analizador de tokens nostr-sdk anterior con una biblioteca dedicada de renderizado de markdown.
La propia especificación del protocolo Marmot recibió una corrección de seguridad en PR #68, que cierra un problema de seguridad al especificar explícitamente HKDF-SHA256 para las derivaciones de clave de imagen en MIP-01, eliminando la ambigüedad que podría llevar a la divergencia en las implementaciones. En MDK, PR #307 sanea las razones de fallo de bienvenida y limita la longitud almacenada, cerrando un hallazgo de seguridad separado.
Amethyst v1.10.0: zaps de Bitcoin en cadena
Amethyst publicó cuatro lanzamientos esta semana, con v1.10.0 como titular. El lanzamiento añade soporte para zaps de Bitcoin en cadena NIP-BC, permitiendo a los usuarios enviar, recibir y mostrar zaps liquidados directamente en cadena mediante transacciones de Bitcoin. Los lanzamientos anteriores de la serie corrigieron la detección de blobs Blossom para rechazar nombres de archivo no conformes (v1.09.2), parchearon las reglas de ProGuard para las compilaciones de escritorio y fusionaron el pull request #2977 para mostrar a los zappers de Bitcoin en cadena como una fila ₿ dedicada en la galería expandida de reacciones. Una pantalla de historial de transacciones en cadena con paginación en curso aterrizó en PR #2974.
AgentNoise: controla agentes de codificación sobre White Noise
AgentNoise de nvk es un ayudante de escritorio nativo en Rust que te permite usar un teléfono con White Noise como superficie de control para sesiones de agentes de codificación locales de Codex y Claude. La herramienta escucha uno o más chats de White Noise, autentica a los remitentes mediante un flujo PIN de primer emparejamiento y lanza agentes de codificación locales a través del launcher configurado. Enviar /claude <prompt> desde tu teléfono abre una nueva sesión de trabajo de White Noise nombrada por el hostname de la máquina y un breve resumen del prompt, luego transmite actualizaciones de progreso y la salida final de vuelta a ese chat. Es intencionalmente Rust-primero y mantiene Node fuera del camino del puente de confianza. El proyecto alcanzó v0.1.24 esta semana, añadiendo respuestas más cortas legibles en teléfono, referencias a trabajos por prefijo corto único y un observador opcional de sesiones locales. AgentNoise ejecuta los CLIs wn y wnd de marmot-protocol/whitenoise-rs como subprocesos, por lo que comparte su transporte Nostr con el propio cliente White Noise.
Auditoría de seguridad de Keycast completada
Keycast, el servidor de firma remota NIP-46 orientado a equipos que almacena las claves privadas Nostr cifradas en reposo en SQLite, completó una auditoría de seguridad en mayo de 2026. La pasada de endurecimiento abordó problemas de autenticación, permisos, integridad de datos y dependencias, y los resultados están documentados en AUDIT.md. Los cambios incluyen: la autenticación HTTP NIP-98 ahora requiere exactamente un tag u y un tag method, rechaza timestamps obsoletos y valida los hashes de payload; la lista de permitidos ALLOWED_PUBKEYS se analiza exactamente y se aplica del lado del servidor; las políticas vacías ahora deniegan por defecto las solicitudes de sign/encrypt/decrypt; la aplicación de claves foráneas está habilitada en las conexiones SQLite; y las rutas de aplicación anidadas como /teams/:id están protegidas del lado del servidor. Una migración SQL normaliza el JSON de permisos de kinds permitidos antiguo al arranque. El proyecto sigue en fase temprana y la auditoría anota elementos residuales antes de confiarle claves reales de equipo.
Scramble: cliente Marmot para escritorio y Android
Scramble (antes OpenChat) es un cliente de escritorio y Android en .NET/Avalonia para el protocolo Marmot, implementando los MIPs 00-04: publicación de KeyPackage (kind:30443), metadatos de grupo con la extensión MLS NostrGroupData, eventos de bienvenida envueltos en gift wrap NIP-59 (kind:444), mensajes cifrados ChaCha20-Poly1305 (kind:445) y adjuntos de medios cifrados con Blossom. Es totalmente interoperable con White Noise y cualquier otro cliente compatible con Marmot.
El proyecto publicó 13 lanzamientos esta semana, con soporte multi-dispositivo como característica principal. Cada dispositivo genera una ranura KeyPackage única (un tag d en kind:30443). Al arranque, Scramble obtiene los KeyPackages propios del usuario desde los relays, detecta los IDs de ranura de los dispositivos pares y los añade automáticamente a los grupos MLS existentes usando el flujo de commit por etapas. La adición automática está restringida a los grupos donde el usuario actual es admin; los grupos no-admin se saltan con una guía para pedir al admin del grupo. Un banner de divulgación de secreto hacia adelante informa a los dispositivos recién enlazados que los mensajes antiguos no están disponibles. Una pasada de reconciliación de ID de ranura (TryReconcileSlotId) maneja dispositivos migrados desde versiones pre-multi-dispositivo emparejando los bytes de KeyPackage del relay contra el material clave local para adoptar el tag d correcto. La reconexión del firmador externo para usuarios de Amber y NIP-46 también se corrigió: el guardia IsConnected que bloqueaba la reconexión automática incorporada de ExternalSignerService se eliminó en los nueve sitios de llamada en NostrService.
Hostr: alojamiento en alquiler P2P sobre Nostr
Hostr (fuente) es una plataforma peer-to-peer de alojamiento en alquiler construida enteramente sobre Nostr. Cubre el flujo completo estilo Airbnb (buscar y listar propiedades, negociar reservas y liquidar pagos) usando cuatro borradores de NIP que el proyecto está desarrollando en paralelo con la aplicación.
El NIP de alojamiento extiende los listados clasificados de NIP-99 (kind:30402 activo, kind:30403 borrador) con tags específicos de alojamiento para tipo (room, house, apartment, villa, hotel, hostel, resort), horas de check-in/check-out, estancia mínima e índices de celdas geoespaciales H3 para búsqueda basada en ubicación con precisión configurable. El NIP de reservas define un protocolo completo de negociación y ciclo de vida: los eventos de reserva reemplazables kind:32122 llevan un ID de intercambio d, un tag a de anclaje al listado y tags p de participantes con roles (buyer, seller, escrow); los rumores de mensajes estructurados kind:1327 entregan contraofertas privadas en la etapa de negociación mediante gift wraps NIP-59 para que la negociación quede fuera de los relays públicos; los eventos de transición append-only kind:1326 crean una traza de auditoría pública una vez que una reserva se compromete. La privacidad del comprador se preserva mediante claves Nostr temporales por intercambio vinculadas a la identidad real del comprador mediante tags participant_proof cifrados. El NIP de escrow define los anuncios de servicios de escrow kind:30303 y las declaraciones de confianza del usuario kind:17388; la implementación de referencia usa contratos inteligentes EVM en Rootstock, con contractBytecodeHash permitiendo a los clientes verificar que el contrato desplegado coincide con una implementación auditada conocida. El NIP de listado de marketplace define tags genéricos compartidos entre todos los perfiles de marketplace NIP-99, incluidos instantBook, negotiable, quantity, securityDeposit, cancellationPolicy y maxDisputePeriod. Esta semana el proyecto preparó su envío a las app stores y fusionó soporte de identidad de cliente MCP para automatización orientada a agentes.
Dos nuevas entradas aparecieron en la plataforma Shakespeare MiniApps esta semana: InkPress, un generador de revistas con IA que publica contenido estructurado tipo revista como eventos Nostr, y PressStr, una plataforma de escritura y publicación para la pila Soapbox.
Publicando esta semana
ngit v2.4.4
ngit publicó v2.4.4, añadiendo ngit sync --trust-server (-t) para casos en que un servidor git está por delante en fast-forward respecto al estado de Nostr. Cuando se detecta esta situación, sync reporta los refs afectados y requiere la bandera para firmar y publicar un evento de estado actualizado; un ajuste de configuración de git nostr.trust-server-domains proporciona una lista blanca separada por punto y coma para servidores que deben ser confiados automáticamente sin la bandera.
Amber v6.1.0-pre3 añade firma PSBT
Amber publicó v6.1.0-pre3 con un mejor diseño para nuevas conexiones de apps, correcciones de crashes y una opción de seleccionar/deseleccionar todo en la pantalla de permisos. PR #438 añade soporte para firmar PSBT a través de las rutas basadas en Intent y basadas en relay NIP-46, permitiendo a Amber firmar Partially Signed Bitcoin Transactions sin exponer el nsec a la app solicitante.
Wisp v1.1.0 estrena respuestas privadas y elimina soporte para Amber
Wisp publicó v1.1.0 con respuestas privadas mediante gift wrap NIP-17 (PR #540), reacciones envueltas en gift wrap y zaps DIP-03 en respuestas privadas (PR #543), traducción automática para notas (PR #523) y una entrada fiat estilo registro en el diálogo de zap. PR #541 migra los zaps privados de un esquema casero de texto plano en DM-relay a DIP-03 con enrutado adecuado de DM-relay. El mismo ciclo de lanzamiento eliminó el soporte del firmador remoto NIP-55 (PR #531), descartando las integraciones con Amber y otros firmadores externos, y eliminó el relay local incorporado (PR #533). Wisp es un cliente social Nostr para Android.
Calendar by Formstr v1.5.4 corrige gift wrap para nuevos participantes
Calendar by Formstr publicó v1.5.4 (el último de una secuencia v1.5.2 → v1.5.4). PR #160 corrige un bug donde editar un evento privado de calendario con nuevos participantes publicaba el evento actualizado con las nuevas pubkeys en tags p pero nunca creaba ni entregaba invitaciones gift wrap a esos participantes, rompiendo el flujo de invitación para adiciones de última hora. PR #156 añade manejo de errores alrededor del descifrado de eventos privados para que los clientes ya no lancen excepciones en eventos indescifrables, y PR #138 corrige tiempos de eventos recurrentes que se desviaban entre zonas horarias.
Applesauce v6.1.0 añade git casts NIP-34 y relays de búsqueda NIP-51
Applesauce publicó v6.1.0 a través de sus paquetes con soporte significativo para NIP-34 (git-sobre-Nostr): applesauce-common añade nuevos casts GitRepository, GitGraspList y FavoriteGitRepos más las fábricas correspondientes, y expone las propiedades reactivas User.favoriteGitRepos$, User.gitAuthors$ y User.graspServers$ para que las aplicaciones puedan listar los repos git seguidos de un usuario, los mantenedores de repos y los servidores GRASP configurados directamente desde el mismo objeto User. El mismo lanzamiento añade soporte para listas de relays de búsqueda kind 10086 NIP-51, una adición reciente a la familia de listas de relays usada para descubrir dónde encontrar datos específicos. applesauce-core gana replaceableAddress en EventCast para búsqueda de direcciones reemplazables NIP-01, más pointer, kind y un ayudante getReplaceableAddressForEvent, y añade un método timeline$() en el cast base User. PR #73 corrige los métodos manuales del pool que silenciosamente descartaban relays offline.
Sprout v0.0.16 estrena el binario Sprig y huddle protocol v2
Sprout de Block, un workspace de equipo basado en relay Nostr auto-alojado donde humanos y agentes de IA comparten las mismas salas y registro de eventos, publicó v0.0.16 de la app de escritorio junto con compilaciones rodantes del nuevo binario todo-en-uno Sprig (PR #605), que empaqueta el arnés ACP, el agente y el MCP de desarrollador en un único binario estilo busybox para despliegue sencillo. La bandera --no-memory añadida en PR #611 permite a los operadores deshabilitar la inyección de memoria central NIP-AE para el arnés ACP. En el lado de tiempo real, PR #609 extiende el protocolo de voz huddle a un encabezado de trama v2 que soporta hasta 10 pares simultáneos.
Nostrord v1.0.3 añade OS keychain y multi-cuenta
Nostrord publicó v1.0.3 con almacenamiento de claves local endurecido usando el keychain del OS y respaldo por frase de contraseña, soporte multi-cuenta y un código QR de bunker tocable que abre la app del firmador en Android.
Angor migra a NIP-44 y estrena endurecimiento de seguridad
Angor, la app de crowdfunding en Bitcoin construida sobre Nostr y Taproot, publicó tres lanzamientos inestables esta semana (v0.2.24, v0.2.25 y v0.2.26) con un conjunto de cambios de endurecimiento de seguridad e integración con Nostr. PR #860 migra la mensajería cifrada Nostr de NIP-04 a NIP-44, reemplazando el esquema basado en XOR obsoleto con cifrado ChaCha20-Poly1305. PR #861 permite subidas de medios Blossom sin una wallet seleccionada usando una clave de autenticación Nostr efímera, desbloqueando subidas para usuarios que aún no han conectado una wallet. La serie de seguridad abordó varias categorías endurecidas: PR #854 añade seguridad de tipos para AngorKey y protección de memoria de mnemónicos, PR #856 aplica validación a nivel de protocolo para timelocks, tasas de comisión, umbrales de dust y reglas de penalización, y PR #851 aplica endurecimiento no rupturista en ocho categorías de severidad media y baja. PR #859 corrige la compatibilidad con GrapheneOS habilitando la compilación AOT y eliminando la generación de código en tiempo de ejecución, y PR #855 evita la pérdida de wallet al hacer swipe-kill en Android persistiendo el estado de la wallet antes de que el OS termine el proceso.
Alby js-sdk v8.0 estrena reconexión multi-relay NWC
Alby js-sdk publicó la línea v8.0 (de v8.0.1 a v8.0.3) con soporte para suscripción NWC multi-relay. PR #516 actualiza la dependencia nostr-tools y habilita la reconexión automática nativa entre múltiples relays, reemplazando el enfoque de polling anterior con lógica de reconexión nativa de relay. PR #542 reemplaza todas las llamadas console.debug con una interfaz de logger inyectable para que los desarrolladores de aplicaciones puedan enrutar los diagnósticos del SDK a través de su propia infraestructura de logging. El lanzamiento elimina el polyfill de WebSocket, requiriendo Node.js 22 o superior para los consumidores del lado del servidor. v8.0.2 añadió una corrección para un bug de importación de crypto utils que rompía ciertos bundlers.
KeyChat v1.41.1 corrige el secreto hacia adelante
KeyChat, una app de mensajería que combina el protocolo Signal con transporte de relay Nostr, publicó v1.41.1+6513. La corrección destacada aplica el secreto hacia adelante eliminando las prekeys únicas de Signal inmediatamente después de un descifrado exitoso, cerrando una brecha donde una prekey retenida podía usarse para descifrar mensajes pasados si el dispositivo era comprometido posteriormente. El lanzamiento también añade vista previa de URL para mensajes que consisten en un único enlace, centraliza la descarga automática de medios bajo un nuevo FileDownloadManager con un umbral automático de 20 MB y refactoriza la obtención de info de relay NIP-11 para forzar el refresco en arranque en frío para que las configuraciones de tarifas de relays de pago siempre se carguen correctamente.
En desarrollo
Citrine fusionó PR #151 implementando la aplicación de NIP-70: el relay Android ahora bloquea los reposts que incrustan contenido de evento protegido, como requiere la especificación. PR #149 añade acciones de visualización y copia para múltiples direcciones de conexión, localhost, Wi-Fi local y Tor, desde la pantalla de configuración del relay. PR #141 añade manejo de desafío AUTH NIP-42 mediante integración con firmador externo con Amber.
Mostro alcanzó la Fase 2 del despliegue de su bono anti-abuso. PR #737 aterriza la lógica de recorte de disputas dirigida por el solucionador: los manejadores de admin ahora consumen la carga útil BondResolution de mostro-core, permitiendo a un admin recortar el bono de cualquiera de las partes al resolver una disputa. La Fase 1.5, fusionada en PR #736, introdujo una acción dedicada PayBondInvoice y un estado WaitingTakerBond, separando el pago del bono anti-abuso del tomador del pago del intercambio del comprador. El cliente móvil añadió la UX completa de la Fase 1.5 en PR #592. Mostro es un protocolo de intercambio de Bitcoin peer-to-peer construido sobre Nostr.
Damus fusionó PR #3773 restaurando el indicador de señal de relay, y PR #3775 corrige relays que rechazaban reconectar tras un fallo de conexión inicial.
rust-nostr fusionó PR #1358 añadiendo traits de finalización de eventos y builders de eventos específicos de NIP, facilitando la construcción de eventos con tipado correcto para funciones de protocolo específicas. PR #1363 backportea una corrección que asegura que el firmador NIP-46 se suscribe a notificaciones antes de enviar la respuesta de conexión, cerrando una condición de carrera donde los mensajes del cliente que llegaban inmediatamente después de connect podían perderse.
dart-nostr fusionó PR #44 añadiendo un resolvedor de relay Namecoin .bit y registros TLSA pin, permitiendo a las aplicaciones Flutter resolver URLs de relay wss://example.bit/ a través de DNS Namecoin a sus direcciones WebSocket reales.
Dart NDK (el kit de desarrollo Nostr para Dart/Flutter, ahora en relaystr/ndk) fusionó PR #464 implementando NIP-77, el protocolo de firma de eventos offline. En el lado del firmador, PR #602 y PR #601 añaden un firmador de eventos específico para web y una abstracción PlatformEventVerifier, permitiendo que las apps Flutter web usen el firmador de plataforma sin una ruta de código separada; PR #604 introduce una fábrica de firmadores de eventos para selección de firmador en tiempo de ejecución. PR #608 añade getDmRelays() para obtener la lista de relays de DM NIP-17 de un usuario (kind:10050), y PR #600 corrige la preservación de campos firmados NIP-46 para que los firmadores remotos no pierdan campos en el ida y vuelta.
Pages by Form* (repo), la app de documentos colaborativos nativa de Nostr de Formstr alojada en pages.formstr.app, fusionó cuatro PRs esta semana endureciendo los flujos de adjuntos cifrados y de gestión de documentos. PR #37 corrige imágenes faltantes en las exportaciones DOCX, HTML y PDF incrustando adjuntos cifrados: obtiene los blobs <encrypted-file> de los servidores Blossom, los descifra con AES-GCM 256-bit usando la clave y nonce almacenados, valida el tipo MIME de la imagen y los convierte a URLs de datos base64 para que las exportaciones preserven las imágenes que solo existen en Blossom en forma cifrada. PR #39 añade un mecanismo de búsqueda de documentos local, PR #38 limpia el flujo de renombrado y PR #40 corrige el manejo de copias de seguridad compartidas.
Zap Cooking fusionó PR #396, la primera fase de una revisión del feed que sienta las bases de las primitivas de renderizado de feed sin ningún cambio visible aún para el usuario. El PR introduce un analizador de tags imeta NIP-92 que lee los slots url, m (MIME), dim (dimensiones), blurhash, alt, x (hash de archivo) y fallback, más un decodificador de blurhash canónico portado a mano (~200 LOC) que produce URLs de datos PNG mediante canvas con un respaldo null seguro para SSR. Cuando los tags imeta están ausentes, el analizador recae en extraer URLs raw de imagen y vídeo del contenido del evento usando las mismas heurísticas que el feed actual ya usa.
Nurunuru (ぬるぬる, tami1A84/null--nostr), un cliente Nostr con variantes nativas Android, iOS y Web que comparten un motor Rust FFI, fusionó su sincronización v1.5.0 Native → Web en PR #176. La sincronización trae varias adiciones de características a la compilación Web que ya se publicaron en Android v1.4.9 e iOS 1.0.4: el NotificationModal ahora expone notificaciones de cumpleaños, detección de zaps de seguimiento mutuo y notificaciones de reacciones con emoji personalizado; el selector de reacciones descarta la fila rápida de reacciones Unicode por defecto y centra la UX en el emoji personalizado; el motor de recomendaciones en lib/recommendation.js filtra usuarios sin iconos o nombres de visualización y prioriza las entradas Following con Recommended cargándose en segundo plano. La entrada de voz es la única característica que va en la dirección opuesta: la compilación Web ya usa ElevenLabs Scribe streaming, y v1.5.0 sincroniza parcialmente el lado Native al SpeechRecognizer estándar del OS (Android) y SFSpeechRecognizer + AVAudioEngine (iOS) mientras la integración Native Scribe completa se difiere a v1.6.
Trabajo de protocolo y especificación
PR #2251 endurece la especificación de eventos protegidos NIP-70: ahora indica explícitamente que los reposts que incrustan el contenido completo de un evento protegido deben ser rechazados por los relays. NIP-70 define el tag - que señala que un autor de nota no consiente que su nota sea republicada. La especificación original cubría el comportamiento de filtrado del relay, pero dejaba el caso de repost ambiguo. Este PR cierra esa brecha. El PR #151 de Citrine implementa la aplicación en el lado del relay esta misma semana.
PR #1653 propone un NIP de Drafts para guardar y sincronizar eventos borradores privados. La propuesta usa eventos reemplazables con un estado draft y cifrado NIP-44 a la propia clave del autor, permitiendo a los clientes guardar trabajos en progreso en los relays sin que esos eventos sean visibles para nadie más. El evento borrador lleva el evento completo de publicación pretendida como contenido cifrado, incluidos su kind y tags eventuales.
Snapshots (PR #2279) es una propuesta abierta para definir un evento snapshot inmutable para preservar una versión exacta de un evento Nostr reemplazable. El evento snapshot lleva el contenido completo del evento reemplazable en un punto dado en el tiempo, con un tag a enlazándolo de vuelta a la dirección del evento reemplazable para que todas las versiones históricas sean consultables juntas. Esto hace posible que los observadores inspeccionen el estado histórico incluso después de que los relays dejen de retener versiones antiguas.
Ola de NIP-05 Namecoin: Esta semana vio un impulso coordinado para añadir resolución NIP-05 .bit a los clientes Nostr. El feed de discusión de NIPs capturó PRs de código abierto contra Aegis (#14, que añade verificación en tiempo de firma en el firmador), nostter (#2128) y dart-nostr (#44), junto con un borrador NIP upstream (PR #2349). El PR de Aegis es notable por colocar la verificación en el lado del productor: el firmador comprueba la cadena Namecoin antes de firmar cualquier evento kind:0 que reclame una identidad .bit y advierte al usuario ante discrepancias, atrapando el problema antes de que el evento llegue a ningún relay.
NIP Deep Dive: NIP-07 (window.nostr para navegadores web)
NIP-07 define la interfaz window.nostr que las extensiones de navegador exponen a las aplicaciones web. Es la interfaz de firmador más ampliamente desplegada en la web, implementada por extensiones como Alby, nos2x, Flamingo y horse.
La interfaz tiene dos métodos requeridos y varios opcionales. window.nostr.getPublicKey() devuelve la clave pública del usuario como una cadena hexadecimal sin exponer nunca la clave privada a la página que llama. window.nostr.signEvent(event) toma un evento parcial con created_at, kind, tags y content, y devuelve el evento firmado completo con id, pubkey y sig añadidos. El punto clave es que la clave privada nunca abandona el contexto aislado de la extensión; la aplicación web envía un evento no firmado y recibe uno firmado de vuelta.
Los métodos opcionales cubren el cifrado: window.nostr.nip04.encrypt y window.nostr.nip04.decrypt para el esquema NIP-04 más antiguo (ahora obsoleto), y window.nostr.nip44.encrypt y window.nostr.nip44.decrypt para el esquema NIP-44 actual. Las extensiones que soportan NIP-44 pueden por tanto manejar tanto el cifrado de mensajes directos como cualquier otra aplicación que necesite cifrado con clave por pubkey sin que la página que llama vea el nsec.
La especificación también incluye una recomendación para los autores de extensiones: cargar los scripts con "run_at": "document_end" en el manifiesto de la extensión para que window.nostr esté disponible síncronamente cuando la página carga, evitando condiciones de carrera donde un cliente comprueba window.nostr antes de que la extensión lo haya inyectado.
Un ejemplo clave de NIP-07 en acción es el proyecto Keycast cubierto arriba. El frontend web de Keycast usa NIP-07 para firmar eventos de autenticación HTTP NIP-98: la app SvelteKit nunca maneja el nsec del usuario directamente. Llama a window.nostr.signEvent para producir el encabezado de autenticación, luego envía ese encabezado a la API de Keycast. Esta arquitectura significa que el material clave permanece en la extensión del navegador durante todo el flujo de gestión de claves del equipo.
{
"id": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2",
"pubkey": "7f8e9d0c1b2a3e4f5d6c7b8a9f0e1d2c3b4a5f6e7d8c9b0a1f2e3d4c5b6a7f8a",
"created_at": 1747785600,
"kind": 1,
"tags": [],
"content": "Hello from a NIP-07 signed event",
"sig": "0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2cdd"
}
NIP Deep Dive: NIP-39 (identidades externas en perfiles)
NIP-39 define cómo un usuario Nostr puede declarar control sobre identidades de plataformas externas en su perfil. Cada declaración usa un tag i dentro de un evento kind:10011, aseverando la propiedad de una cuenta específica en otra plataforma junto con una prueba que puede ser verificada independientemente.
Cada tag sigue el formato ["i", "platform:identity", "proof"], donde platform:identity combina el nombre de la plataforma y el nombre de usuario con un separador de dos puntos (github:semisol, twitter:semisol_public). proof apunta a un artefacto verificable en la propia plataforma.
Para GitHub, la prueba es un ID de Gist. El usuario crea un Gist público desde su cuenta de GitHub que contiene el texto Verifying that I control the following Nostr public key: npub1.... Un cliente verificando la reclamación obtiene https://gist.github.com/<identity>/<proof> y comprueba que el Gist fue creado por el nombre de usuario de GitHub reclamado y contiene la pubkey esperada. Para Twitter la prueba es un ID de tweet, para Mastodon un ID de post, y para Telegram una referencia de mensaje en un grupo público.
El nombre del proveedor de identidad debe contener solo a-z, 0-9 y los caracteres ._-/, y no debe contener :. Los nombres de identidad deben normalizarse a minúsculas, usando el alias principal cuando existen varios.
La discusión de NIP-05 Namecoin .bit que ocurre esta semana muestra el papel de NIP-39 en la pila de identidad más amplia: proporciona una forma estandarizada e independiente del relay para cruzar referencias de una clave Nostr con una identidad establecida en otro lugar, sin requerir ninguna autoridad central de verificación. Un cliente puede verificar independientemente la prueba obteniendo un artefacto público en la plataforma nombrada, y la prueba está vinculada a la pubkey Nostr específica en el texto del Gist o tweet, no a una credencial genérica de plataforma.
{
"id": "b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3",
"pubkey": "7f8e9d0c1b2a3e4f5d6c7b8a9f0e1d2c3b4a5f6e7d8c9b0a1f2e3d4c5b6a7f8a",
"created_at": 1747785600,
"kind": 10011,
"tags": [
["i", "github:semisol", "9721ce4ee4fceb91c9711ca2a6c9a5ab"],
["i", "twitter:semisol_public", "1619358434134196225"],
["i", "mastodon:bitcoinhackers.org/@semisol", "109775066355589974"]
],
"content": "",
"sig": "1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3eff"
}
Eso es todo por esta semana. Si estás construyendo algo o tienes noticias que compartir, envíanos un DM en Nostr o encuéntranos en nostrcompass.org.