Nostr Compass #36
Bienvenidos de nuevo a Nostr Compass, vuestra guía semanal de Nostr.
Esta semana: Amber endurece la autenticación con relays y cifra los secretos almacenados, Cambium firma para sitios web bajo carga de relay-auth, Citrine aloja grupos y sitios estáticos en un relay de teléfono, Vector encola la moderación bajo spam y sincroniza silencios entre dispositivos, Sonar añade respuestas en malla con hilos, Nostria publica pódcasts, y Nail conecta el correo como eventos gift wrap. Las versiones cubren el estado de grupos de MDK, acuñación de insignias, emparejamiento de firmante por QR, firma en navegador en Android y una biblioteca compartida de wallet connect. El trabajo de protocolo abarca parches de comentarios, metadatos de archivos cifrados, formato de hilos, garantías de reinicio de Marmot y listas de membresía de Concord. Análisis en profundidad: insignias y comentarios.
Historias Principales
Amber 6.5.0 cierra un confused deputy de relay-auth y cifra los secretos almacenados
Amber es un firmante Android de NIP-55 (intents de firmante en Android) y NIP-46 (firma remota mediada por relays). La versión 6.5.0 cierra cuatro brechas divulgadas: un confused deputy en la autenticación con relays que permitía a cualquier llamante obtener un evento NIP-42 (autenticación cliente-relay) de kind 22242 para relays que el usuario nunca había aprobado; una brecha de replay de NIP-46; secretos de conexión y claves locales en texto plano que ahora se cifran en reposo con sobre cifrado; y un lote de endurecimiento de ocho puntos que cubre autorización del llamante antes de descifrar, análisis de permisos fail-closed, advertencias de ws:// sin cifrar, pantallas QR seguras, redacción de registros, borrado perezoso de claves al cerrar sesión y uso opcional del Keystore con dispositivo desbloqueado.
La versión 6.5.1 vuelve a cifrar los secretos NIP-46 almacenados cuando la clave del Keystore rota tras activar o desactivar el requisito de dispositivo desbloqueado, y corrige un fallo del editor de permisos. La versión 6.5.2 deja de descifrar columnas que la lista de aplicaciones nunca renderiza, cachea el handle del Keystore, precalienta la caché de cuentas al arrancar y aplica debounce a las notificaciones de estado de relay.
La 6.4.0 de la semana pasada hizo explícitas las decisiones de firma agrupadas; 6.5.x cambia lo que Amber autorizará en absoluto.
Cambium 0.4.0 firma para sitios web y alivia ráfagas de relay-auth
Cambium es un proxy Android de NIP-55 hacia un firmante hardware Heartwood sobre NIP-46. Se publicaron seis versiones en dos días.
La versión 0.4.0 extiende la firma a sitios web. Una página puede solicitar una firma mediante un callback nostrsigner: validado sin heredar los permisos concedidos a aplicaciones nativas, de modo que una pestaña del navegador no pueda tomar prestada la aprobación de otra app. La misma versión corrige la forma mínima de evento de la especificación: un evento que solo lleva kind y content ahora firma correctamente, con Cambium aportando la identidad NIP-46 emparejada, la marca de tiempo actual y un array de etiquetas vacío antes de entregar el evento a rust-nostr. La instrumentación nativa de rust-nostr pasó a ser una puerta obligatoria de integración continua en el mismo cambio.
La versión 0.3.6 repara el emparejamiento con firmantes que siguen la especificación. La compilación antigua de rust-nostr en Cambium solo aceptaba la cadena literal ack como resultado de una llamada connect de NIP-46, así que un firmante que respondía devolviendo el secreto de la URI del bunker — lo que pide la especificación actual y lo que hace el firmware de Heartwood — terminaba el emparejamiento con un error de respuesta inesperada. Pasar de rust-nostr 0.44.2 a 0.44.8 hace aceptables ambas formas, verificado contra hardware en vivo y contra nak bunker, que sigue respondiendo ack.
Las versiones 0.4.1 a 0.4.3 tratan el control de admisión bajo carga. La versión 0.4.1 reserva un hueco en cola para reacciones, publicaciones, eliminaciones y cifrado por delante de la autenticación con relay y el descifrado en segundo plano, acota las llamadas en cola, las descarta cuando el llamante ha agotado el tiempo de espera y devuelve un resultado terminal de no disponible en sobrecarga en lugar de abrir una pantalla de firma en primer plano. La versión 0.4.2 descarta sesiones NIP-46 caducadas o inactivas mucho tiempo antes de la siguiente petición y deja que copias concurrentes del mismo evento de autenticación kind 22242 compartan una firma hardware. La versión 0.4.3 admite como máximo un desafío de autenticación distinto por identidad en el worker hardware, nunca reintenta la autenticación internamente y abre un enfriamiento de sesenta segundos por identidad tras un timeout, respondiendo aún a duplicados exactos en caché. Las mediciones de las notas de la versión provienen de un teléfono GrapheneOS conduciendo Amethyst: una ráfaga en arranque en frío produjo treinta y tres respuestas inmediatas de sobrecarga y trece peticiones completadas sin timeouts del firmante, y un inicio de sesión nuevo durante una ráfaga de autenticación volvió 1,254 segundos después de la aprobación.
Citrine 3.1.0 convierte un relay de teléfono en anfitrión de grupos y de sitios
Citrine es un relay Android en el dispositivo. La versión 3.1.0 añade tres capacidades que cambian lo que el relay puede alojar.
El soporte de NIP-29 (grupos gestionados por relays), la especificación de grupos basada en relay donde el propio relay guarda membresía y estado de moderación, significa que un teléfono puede alojar un grupo en lugar de unirse a uno. El soporte de NIP-86 (API de gestión de relays), la API de gestión de relays que expone acciones administrativas por JSON-RPC autenticado, llega con una pantalla de ajustes, así que listas de permitidos y baneos pueden gestionarse desde la API además de desde la app. El soporte de sitios web estáticos de NIP-5A permite al relay servir nsites a clientes web, con una lista de exploración modernizada que incluye iconos, búsqueda, orden por última actualización, progreso de instalación, descripciones y un conjunto configurable de relays para obtenerlos que por defecto es nsite.run, nos.lol y nostr.land.
La superficie de moderación creció en paralelo en la misma versión. Banear una clave pública localmente ahora ofrece purgar los eventos almacenados de ese autor, una lista configurable REJECTED_KINDS bloquea kinds que el operador no quiere almacenar, y el control de acceso puede importar listas existentes. Una herramienta de retransmisión empuja eventos almacenados de nuevo a relays seleccionados, lo que da a un archivo guardado en el teléfono una forma de resembrar la red. La versión también elimina la extensión WebSocket permessage-deflate, aprieta la ruta caliente de consultas, corrige el fallo de Tor al arrancar o detenerse cuando cambia el ajuste de exposición vía Tor, y mueve los registros a una base de datos local con logcat limitado a compilaciones de depuración.
Vector 0.4.2 hace que la moderación comunitaria sobreviva a una ola de spam
Vector es un mensajero Concord de escritorio y Android. La versión 0.4.2 se centra en la moderación bajo carga.
Los baneos rápidos antes se sobrescribían entre sí. Ahora se encolan, se apilan y se resuelven como una sola operación, así que banear una ola de cuentas cuesta una rotación de claves en lugar de una por cuenta. Aceptar una invitación a una comunidad ya disuelta ahora explica por qué y elimina la invitación de todos los dispositivos del usuario, y disolver una comunidad propia la quita de la lista de comunidades en todas partes, una corrección que llegó en la versión 0.4.3. Los mensajes comunitarios que llegan durante una puesta al día en segundo plano ya no suenan notificaciones como si acabasen de enviarse, y el indicador de escritura expira desde el momento del envío para que una señal retrasada no permanezca en un canal.
La lista comunitaria fragmentada definida por Concord pasó una revisión cruzada con Armada, el otro cliente Concord. Los renombres ya no inflan la lista, los empates se resuelven igual en ambos clientes, y los datos sin cambios ya no se republican a relays. Silenciar también salió del camino de mensajes directos: un usuario puede silenciar a alguien directamente desde una comunidad sin historial previo, y el silencio aplica a notificaciones e insignias en canales y mensajes directos dejando visibles los mensajes. Los mensajes fijados pasaron a ser una superficie compartida del canal con enlaces clicables, y las ediciones de un fijado lo siguen donde aparezca. Listas de bloqueo, silencios y apodos ahora se sincronizan entre dispositivos del usuario, al igual que chats fijados. La versión 0.4.3 también deja de anunciar que el usuario escribe cuando otro cliente Nostr está conectado con la misma identidad, y desbloquea el arranque de Tor en Windows, que se había congelado al quince por ciento tanto en x64 como en ARM64.
Sonar trae respuestas en hilo a un mensajero en malla con NIP-C7
Sonar es un mensajero Bluetooth en malla y Nostr. La versión 0.1-alpha.13.1 añade respuestas al estilo Signal en chat NIP-C7 kind 9, más menciones, reensamblado Bluetooth acotado, límites de copia de seguridad, verificación de firma de ruta en malla y respaldo push FCM. Las versiones 0.1-alpha.13.2 y 0.1-alpha.13.3 corrigen cierres al abrir el chat en Android y solapamiento del teclado en iOS.
Nostria empieza a publicar pódcasts y pide a los relays que cuenten
Nostria es un cliente web. Las versiones 4.1.70 y 4.1.71 añaden publicación de pódcasts para suscriptores premium, con episodios como eventos Nostr firmados. La versión 4.1.69 usa COUNT de NIP-45 (consultas de recuento en relays) para totales de reacciones, respuestas y zaps en feeds y completa la localización. La 4.1.67 de la semana pasada amplió la administración de comunidades cifradas.
Versiones
MDK 0.9.14: historial de grupo fail-closed mediante creación de grupos más rápida
MDK es el kit de desarrollo Rust para Marmot, un protocolo de mensajería grupal cifrada transportado sobre Nostr. La versión 0.9.12 hace fail-closed varias rutas de estado de grupo en lugar de adivinar. Un ancla de bifurcación ausente es ahora un error duro (PR #1329), una propuesta de salida se persiste de forma atómica para que un fallo no deje una salida a medias (PR #1360), y la reproducción de incidentes se niega a adivinar un formato en flujos JSON delimitados por saltos de línea sin manifiesto (PR #1140). Las pruebas de convergencia se ampliaron a la vez, con recuperación entre rutas de historial retenido (PR #1350), garantía de convergencia entre adaptadores (PR #1372) y campañas de convergencia aisladas generalizadas (PR #1357). El diagnóstico de rechazo de relay se conserva en lugar de colapsarse en un fallo genérico (PR #1361).
La versión 0.9.13 llegó el 18 de agosto con formato de almacenamiento v2 (PR #1421), raíles de migración y escrituras delta sustituyendo instantáneas de cuenta en vivo (PR #1435), más puesta al día de invitaciones más rápida (PR #1444) y bindings de macOS (PR #1402). La versión 0.9.14 siguió el 19 de agosto con pulido de creación de grupos: imágenes fundacionales pre-subidas (PR #1498), agrupación de KeyPackage (PR #1494), retención atómica del mensaje inicial (PR #1497) y publicación de perfil con relays propios de la cuenta (PR #1495). MarmotKit 0.9.14 y wn-agent 0.9.14 se publican con el crate principal.
Divine Mobile 1.0.20: acuñar una insignia sin salir de la app
Divine Mobile es un cliente de vídeo corto que publica y recupera vídeo a través de Nostr. La versión 1.0.20 permite acuñar una insignia NIP-58 (eventos de premio firmados descritos en el primer análisis en profundidad de este número) y entregarla a alguien sin salir de la app. Tocar una insignia en un perfil explica qué hizo falta para ganarla, la parte de la especificación que suele quedar sin implementar porque el evento de definición y el de premio se almacenan por separado.
El resto de la versión es trabajo de cliente: tema claro, recorte, rotación y volteo en el editor stop-motion, borradores a un toque del grabador, sincronización de subtítulos con el vídeo, un feed que deprioriza material ya visto, soporte de lector de pantalla en editor, grabador y pestañas de perfil, manejo de movimiento reducido, y ajustes de cuenta que gestionan correo y contraseña de Divine y vinculan o desvinculan cuentas. Los vídeos eliminados ya no dejan estado local, y los marcadores persisten. La 1.0.19 de la semana pasada endureció el aislamiento de cuentas y la validación de mensajes privados; la emisión de insignias es una nueva superficie de publicación encima de eso.
ClipRelay 0.2.0: emparejar un firmante con una cámara
ClipRelay sincroniza el portapapeles entre dispositivos sobre Nostr. La versión Android 0.2.0 añade inicio de sesión QR nostrconnect://, para firmar con una app firmante en otro teléfono, y escaneo con cámara de URLs de bunker, eliminando el hábito de pegar una cadena con secreto a través de un mensajero. La conexión bunker ahora agota el tiempo a los sesenta segundos en lugar de colgarse, y el botón de reintento tras un fallo de inicio con Amber funciona. La versión de escritorio 0.2.0 incluye el timeout y las correcciones de la pestaña de inicio de sesión.
La versión 0.1.4 añadió sincronización de portapapeles sensible con caducidad corta en relay, relays de sesión de firmante fijados, y una sonda de vida que exige un ida y vuelta real en lugar de un EOSE sintetizado localmente. La 0.1.3 de la semana pasada restauró conexiones tras periodos de inactividad.
Bark 1.3.9: un firmante de navegador que funciona en Android
Bark es una extensión de navegador que proporciona la interfaz NIP-07 window.nostr, el objeto que una página web invoca para pedir firma u operación de cifrado. La versión 1.3.9 declara soporte Android para la compilación de Firefox, de modo que el listado de complementos se instala en un teléfono. Firefox en Android no implementa la API de ventanas, así que toda aprobación que abría una ventana emergente habría sido denegada de plano; la superficie de aprobación ahora recurre a una pestaña en primer plano donde cerrar deniega, revisar la trae al frente, y el fondo la cierra cuando la petición termina. Las notas de la versión registran verificación en un Pixel 10 Pro XL con GrapheneOS y Firefox 153.0.4, y dejan claro que Chromium en Android compila fuera el subsistema de extensiones, así que ningún navegador Android derivado de Chromium puede ejecutar Bark.
La versión 1.3.8 corrigió un defecto de interoperabilidad NIP-46 en la otra dirección. Bark sondeaba un dialecto compacto de firma Heartwood enviando el evento como objeto JSON, que firmantes estrictamente tipados incluidos nak y bunkers sobre rust-nostr no pueden analizar y descartan en silencio, de modo que la firma se quedaba colgada. La sonda ahora solo se envía a firmantes que se identificaron como Heartwood, y todo otro firmante recibe una llamada estándar sign_event desde la primera firma.
Bray 3.0.0 y Toll Booth 6.0.0 migran a una biblioteca compartida de wallet connect
Bray y Toll Booth pagan ambos mediante NIP-47 Nostr Wallet Connect, la especificación que permite a una aplicación solicitar pagos a un monedero sobre eventos Nostr cifrados. Bray 3.0.0 y Toll Booth 6.0.0 declaran cada uno un cambio incompatible adoptando nwc-kit para pagos con monedero, y Toll Booth elimina su flujo de credenciales del pagador en el mismo cambio. Ambos publican compilaciones reproducibles cuya salida fue idéntica byte a byte en dos ejecutores independientes, con el hash del tarball impreso en las notas de la versión para que un lector pueda verificar el artefacto del registro.
Tres parches de Toll Booth siguieron: 6.0.1 fija la clave de host de despliegue negociada, 6.1.1 fija cashu-ts a la versión que apunta su parche, y 6.1.2 restaura una compilación de imagen.
NoorNote 1.3.4: unirse a comunidades cifradas desde un enlace de invitación
NoorNote es un cliente Nostr para escritorio, web y Android. La versión 1.3.4 añade comunidades cifradas Armada y Concord como complemento: un usuario se une mediante enlace de invitación, ve las comunidades unidas listadas en ajustes, y recibe notificaciones de actividad. La misma versión añade un control para ocultar publicaciones citadas externas, los destacados que citan un párrafo de un artículo web, globalmente o por autor, ocultando también los reposts de ellos y manteniendo visibles los destacados propios. La resolución de perfil también se reparó, de modo que los perfiles ya no se renderizan como clave pública truncada o marcador anónimo.
La versión 1.3.5 añade un expansor para notas largas y corrige el diseño del campo de enlace de invitación Armada. La 1.3.2 de la semana pasada movió el descubrimiento de artículos al grafo social; la membresía comunitaria es una superficie aparte.
Mostro mueve el chat de disputas fuera del gift wrap
Mostro es un daemon de comercio entre pares cuyas órdenes y mensajes viajan como eventos Nostr, con mostro-core como biblioteca compartida y Mostro Mobile como cliente. Mobile 1.3.2 migra el chat de disputas del gift wrap NIP-59 (sobres que ocultan metadatos) a un sobre de chat kind 14 y respalda el backlog con cursores duraderos por conversación. mostro-core 0.14.5 serializa el identificador del rumor dentro del gift wrap (PR #164), 0.14.4 corrige un error de media de valoraciones (PR #163), y Mobile 1.3.1 cambia a servidores Blossom que retienen adjuntos de chat cifrados. Usar daemon 0.18.2 o 0.18.4.
NYM 3.73.522: chats grupales cifrados y almacenamiento local cifrado
NYM es un cliente Nostr con integración propia de asistente. La versión 3.73.522 cifra el almacén SQLite local tras 3.73.521 que refina el chat grupal cifrado, y 3.73.520 corrige una rotura de política de seguridad de contenido y la presentación duplicada de mensajes nuevos.
Morganite 0.0.4: verificar un blob antes de cachearlo
Morganite es un servidor Android Blossom, el protocolo de medios donde un archivo se direcciona por el hash SHA-256 de su contenido y se sirve desde cualquier host que lo tenga. La versión 0.0.4 verifica el hash de un blob durante la descarga en un solo paso antes de cachearlo, la comprobación que hace significativa la dirección por contenido en el lado receptor. La versión también rastrea el tamaño de caché de forma incremental en lugar de reescanear el directorio en cada guardado, mueve llamadas de red bloqueantes a hilos de entrada y salida, reutiliza instancias Tika para detección MIME, y persiste registros en una base de datos local.
Recién descubiertos
Nail lleva el correo a Nostr como eventos gift wrap
Nail es un puente de correo con licencia MIT y cliente web del equipo Formstr, el grupo detrás de Formstr y nostr-calendar. Llegó al lanzamiento el 18 de agosto con PR #7, un cambio de veintidós archivos que añadió etiquetas k a eventos de correo, recuperación de claves en ajustes y un mensaje de bienvenida. Su despliegue corre en mailstr.app, que sirve el propio registro _smtp NIP-05 (esquema DNS que mapea un nombre en un dominio a una clave pública Nostr) del puente.
El correo en sí es un evento Nostr. Las constantes del cliente definen un rumor de correo kind 1301 llevado dentro de un gift wrap NIP-59 kind 1059, de modo que un mensaje llega al destinatario mediante el mismo sobre que oculta metadatos usado para mensajes directos privados. Los relays de entrega provienen de una lista de bandeja de entrada NIP-17 (mensajes directos privados) kind 10050 con una lista de relays NIP-65 kind 10002 detrás, las carpetas son etiquetas NIP-32 (eventos de etiqueta) kind 1985 bajo un espacio de nombres mail, y los ajustes del cliente viven en un evento de datos de aplicación NIP-78 kind 30078. Los adjuntos mayores de 60.000 bytes van a Blossom en lugar de al evento, porque NIP-44 (cifrado) limita el texto plano cifrado a 65.535 bytes. Una dirección es un npub en un dominio, y un dominio local sin registro NIP-05 se trata como un buzón inexistente.
La mitad puente es un servidor LMTP Node que corre junto a un despliegue mailcow sin parchearlo: Postfix enruta dominios coincidentes al puente, y el puente inyecta respuestas de vuelta por SMTP. Ese diseño obliga a una respuesta honesta a la pregunta más dura de un puente de correo: qué demuestra una cabecera From. La ruta de recepción de Nail clasifica cada mensaje en uno de cuatro estados de procedencia: el puente configurado lo selló y se niega a retransmitir un remitente que no verificó upstream, el usuario lo selló él mismo, el registro NIP-05 de la dirección resuelve a la clave selladora, o nada corrobora la cabecera. En ese último caso la interfaz recurre a la clave pública selladora, la única identidad que el evento puede probar de verdad. Las llamadas a la API del puente se autentican con eventos HTTP firmados NIP-98 (autenticación HTTP mediante eventos firmados).
Glow almacena etiquetas de monedero en relays bajo una identidad derivada de passkey
Glow es un monedero Lightning autocustodial de Breez. El inicio de sesión con passkey deriva una identidad Nostr, y las etiquetas del monedero se listan desde relays y se guardan en relays bajo esa identidad, con duplicados idénticos byte a byte colapsados entre cobertura parcial de relays.
En desarrollo
Amethyst reconstruye el flujo de decisión de autenticación con relays
Amethyst es un cliente Nostr Android. Un bloque de trabajo fusionado remodela cómo maneja la autenticación cliente-relay NIP-42. La interfaz de permisos y el flujo de decisión se rediseñaron (PR #3899), la autenticación ahora espera a que un desafío se resuelva en lugar de agotar el tiempo (PR #3905), las cuentas nuevas autentican por defecto siempre con relays (PR #3931), y una opción de «iniciar sesión siempre» se honra para relays que la cuenta no usa (PR #3937). La autenticación también reconoce grupos NIP-29 y comunidades Concord como espacios unidos (PR #3906), lo que evita que un grupo alojado en relay parezca un relay desconocido cada vez que se abre.
Dos cambios más tocan superficies de protocolo. La minería de prueba de trabajo bajo NIP-13 (nonce PoW) actualiza created_at mientras mina y gana un análisis de ruta GPU (PR #3911), y los hosts de napplet a pantalla completa manejan insets del método de entrada (PR #3932). Una copia de seguridad guiada de claves en el primer arranque con entrada en ajustes también se fusionó (PR #3909), junto a la capacidad de silenciar chats públicos (PR #3939).
nostrord implementa una propuesta no fusionada de clave de cifrado
nostrord es un cliente de chat Nostr organizado en torno a grupos acotados por relay. Fusionó una implementación de NIP-4e, una propuesta no fusionada para desacoplar el cifrado de mensajes de la clave de identidad que Compass describió por última vez en el número del 15 de julio. La cuenta anuncia su propia clave de cifrado kind 10044, guarda la mitad privada localmente y descifra mensajes directos entrantes en proceso, sacando un bunker o extensión de navegador del camino de lectura por completo (PR #261). El emparejamiento de dispositivos sobre kinds 4454 y 4455 mueve esa clave a un segundo dispositivo, y un autoarchivo republica historial dirigido a la nueva clave. El envío se dirigió primero a la clave anunciada (PR #247), y un seguimiento corrigió emparejamiento que negoció con éxito sin entregar la clave (PR #271). El pull request indica que el formato en wire sigue la implementación desplegada de Jumble donde diverge de la propuesta abierta, lo que sitúa la definición operativa de esta especificación en código publicado en lugar del documento.
La identidad de grupo se apretó en el mismo lote. Un identificador de grupo es ahora único solo dentro de su relay (PR #269), así que el mismo identificador en dos relays se trata como dos grupos (PR #272), y las publicaciones de hilo se renderizan como publicaciones de foro (PR #274). El churn de conexión que producía repetidas solicitudes de firma kind 22242 también se detuvo (PR #268), la misma clase de presión sobre el firmante en la que Cambium trabajó tres versiones esta semana.
nostream añade un monitor de relay y acuña códigos de invitación
nostream es una implementación de relay en TypeScript. Fusionó un worker de clúster y planificador de sondas que publican eventos de monitorización de relay NIP-66 (especificación de descubrimiento que permite a un monitor anunciar datos de vida y capacidad sobre otros relays) (PR #724), con esquema de ajustes y valores por defecto (PR #689) y pruebas de integración (PR #733). Una herramienta de línea de comandos ahora acuña códigos de invitación NIP-43 (esquema de metadatos de acceso a relay) (PR #732), y el relay por fin anuncia prueba de trabajo NIP-13 en su lista de soportados (PR #680), que ya había implementado sin anunciar. Los trabajos de máquinas expendedoras de datos también ganaron migración de persistencia y repositorio (PR #727), y el relay ahora atrapa peticiones de trabajo NIP-90 (peticiones de trabajo de máquinas expendedoras de datos) y las registra por el repositorio de trabajos (PR #729).
rust-nostr corrige un identificador de gift wrap y rechaza reposts protegidos
rust-nostr es la biblioteca Rust y kit de desarrollo detrás de gran parte del trabajo de clientes Rust y móviles de este número. Ahora asegura que el identificador del rumor se calcula antes de cifrar el sello del gift wrap (PR #1444), la misma clase de defecto que Mostro corrigió en su propia biblioteca esta semana. Su relay local rechaza un repost de un evento protegido NIP-70 (PR #1445), la protección para la que existe esa especificación, y el análisis de respuestas NIP-47 tolera importes ausentes y nulos (PR #1450) en lugar de fallar con un monedero que los omite. El análisis de URL de relay se endureció (PR #1451).
NDK añade mensajes directos poscuánticos y elimina una dependencia GPL
NDK es un kit de desarrollo Dart para Nostr. Fusionó cifrado poscuántico híbrido para mensajes directos usando ML-KEM-1024, el mecanismo de encapsulación de claves reticular estandarizado como FIPS 203 (PR #713), colocándolo junto al acuerdo de claves clásico en lugar de en su lugar. Un cambio aparte sustituyó una implementación Dilithium solo GPL-3.0 por fips204, el estándar de firma ML-DSA (PR #712), lo que elimina una restricción de licencia para aplicaciones que incrustan el kit. Las conexiones también pasaron a una identidad cada una (PR #710).
Nostter añade listas de marcadores, insignias de perfil y subidas Blossom
Nostter es un cliente web. Fusionó soporte para las formas estándar y heredadas de listas de marcadores NIP-51 (PR #2311), actualizó su manejo de insignias de perfil NIP-58 (PR #2281), añadió un cargador de medios Blossom (PR #2298), y ahora muestra un identificador NIP-05 (nombre de verificación DNS) en el autocompletado de menciones (PR #2303).
Zap Cooking ata rutas de administración a peticiones firmadas y cifra conexiones de monedero almacenadas
Zap Cooking es un sitio de recetas construido sobre eventos Nostr de formato largo. Un lote de seguridad cifra cadenas de conexión Nostr Wallet Connect almacenadas en reposo dentro de un sobre NIP-44 (PR #622), sustituye una comparación falsificable de clave pública en rutas administrativas por autenticación HTTP NIP-98 (esquema que firma un evento para autorizar una petición HTTP) (PR #626), y borra datos de cuenta al cerrar sesión acotando registros NIP-46 pendientes (PR #627).
Actualizaciones de NIPs y trabajo de especificación del protocolo
NIPs
Ningún pull request se fusionó en nostr-protocol/nips durante esta ventana. Se abrieron seis propuestas tras cerrarse el número anterior, tres de ellas el 18 de agosto después de que el borrador circulara por primera vez.
NIPs PR #2438 propone NIP-9A, parcheo basado en comentarios. Un parche es un comentario kind 1111 que referencia el evento parcheado como padre cuyo content comienza con la etiqueta literal PATCH, seguida de líneas de parche. Una línea que comienza con un número edita el content del objetivo en la forma <index> -<deleted> +<inserted> <caracteres insertados>, contados en caracteres unicode en lugar de bytes, y una línea que comienza con t sustituye una etiqueta legible por humanos como title, description, subject o picture. El diseño es deliberadamente retrocompatible: un cliente que no entiende el formato muestra el parche como un comentario etiquetado ordinario, y un cliente que sí lo entiende aplica el parche y oculta el comentario. La propuesta nombra kinds 1, 11, 1111, 24 y 1621 como parcheables y pide a escritores y lectores rechazar parches demasiado grandes, demasiado numerosos o publicados mucho después del evento original, un intento explícito de evitar que la función se convierta en un canal general de edición para eventos inmutables.
NIPs PR #2437 propone cifrado de archivos para NIP-94, la especificación de metadatos de archivo que describe un archivo subido en un evento kind 1063. Añade tres etiquetas opcionales: encryption-algorithm, con aes-gcm como único valor listado, más decryption-key y decryption-nonce codificados en hex. La semántica de etiquetas cambia en consecuencia, con m describiendo el tipo MIME antes del cifrado, x guardando el hash del archivo cifrado, y ox el hash del original, y cualquier fuente thumb, image y fallback cifrada bajo la misma clave y nonce. El propósito declarado es que un operador Blossom público que aloja los bytes no pueda decir qué son, y el autor enmarca el cambio como copiar las propiedades de cifrado de mensajes directos NIP-17 en metadatos de archivo para que el mismo tratamiento funcione dentro de una etiqueta imeta.
NIPs PR #2436 enmienda NIP-7D, la especificación de hilos de foro construida sobre eventos de hilo kind 11 con comentarios NIP-22 kind 1111 como respuestas. Añade una sección de formato que indica que una publicación de hilo puede formatearse como una nota kind 1, con imágenes en línea, enlaces y referencias NIP-27 (referencias de texto), y también podría soportar Djot, un lenguaje de marcado ligero con gramática inequívoca. El argumento del autor es que dejar el formato sin especificar invita a una implementación Markdown por defecto eventual, y el pull request señala a squalk como implementación Djot existente.
NIPs PR #2439 añade métodos assign y unassign a NIP-86 (comandos de gestión de relay), de modo que un administrador de relay pueda conceder permisos de administración a otra pubkey sin compartir la clave maestra.
NIPs PR #2442 sucede la propuesta de pistas de audio que Compass cubrió en enero mientras ese borrador permanecía abierto; el pull request anterior se ha cerrado desde entonces y este se publica en producción en lightning.fm como eventos de pista kind 31337, con objetos de lanzamiento kind 31339, perfiles de banda, colaboradores por pista, y repartos opcionales de zap NIP-57 manteniendo ventas en NIP-99. El contrato de interoperabilidad está publicado en lightning.fm/interop, y el editor de escritorio y el daemon de vendedor autoalojado son código abierto.
Marmot
Marmot PR #416 se fusionó el 13 de agosto y añade un contrato de durabilidad y reinicio al núcleo del protocolo. Los documentos adoptados ya definían convergencia determinista, material retenido de padre candidato, orden publicar-antes-de-aplicar, y comportamiento fail-closed ante historial ausente, sin una regla inequívoca sobre qué ocurre cuando un proceso se interrumpe en las costuras entre ellos. El cambio define hechos lógicos recuperables, equivalencia de reinicio, límites de interrupción de publicación y convergencia, transiciones atómicas para observadores, manejo de material ausente o corrupto, y recuperación de efecto de aplicación, y añade escenarios de conformidad de fallo y reinicio para cada uno. Deja transacciones, diarios, instantáneas, estrategia de reproducción, planificadores y formatos de almacenamiento definidos por implementación, y declara que no requiere cambio de codificación en wire. El fallo específico que cierra es una publicación aceptada externamente pero no confirmada localmente, o una rama seleccionada aplicada parcialmente, produciendo resultados de protocolo dependientes de implementación tras un reinicio.
Concord y CORDs
Concord PR #18, cubierto previamente en el número de la semana pasada como propuesta abierta, se fusionó el 15 de agosto. Fragmenta la lista comunitaria cifrada entre eventos kind 33302, elimina el límite de cincuenta membresías, y poda entradas retiradas para mantener la lista dentro de límites de tamaño de relay. Las notas de la versión de Vector esta semana registran la mitad del cliente de ese cambio, incluida resolución de empates y la decisión de dejar de republicar datos sin cambios.
Concord PR #22 propone brokers de audio y vídeo propiedad de la comunidad. La entidad de metadatos CORD-02 llevaría una lista opcional av_brokers junto a sus relays, evolucionando por edición como el resto de esa entidad, y el rendezvous CORD-07 tomaría de esa lista, o del broker propio del miembro cuando la comunidad no publica ninguno, ordenado por el desempate existente por clave de sala. La etiqueta broker en presencia sigue siendo legible y útil para informar una división residual, y el argumento de la propuesta para degradarla del enrutamiento es directo: enrutar sobre ella deja que la entrada no confiable de un compañero miembro supere la instrucción propia de la comunidad.
Concord PR #23 hace normativo un comportamiento de implementación existente en CORD-05. Antes de persistir una unión, la edición de metadatos génesis del propietario debe abrir bajo las claves entregadas, con planos rotados anclados en el par de compactación. El pull request declara de entrada que esto nunca fue una vulnerabilidad en vivo: la aceptación de paquetes de Vector ya rechaza un paquete cuya raíz entregada no puede abrir el génesis del propietario y nunca aparca una invitación para una comunidad ya retenida, y Armada ya descarta cualquier paquete que movería la base de una comunidad retenida. La brecha era que ningún comportamiento estaba exigido por la especificación, así que un cliente fiel a la especificación podría haber publicado la versión vulnerable.
Los documentos de actualización de Blossom, las propuestas de aplicación Napplet y la especificación Gamma Markets no registraron cambios en esta ventana.
Análisis en profundidad de NIPs
Insignias (NIP-58)
NIP-58, definido por su especificación principal, da a una identidad Nostr una forma de otorgar un token con nombre a otra, y da al destinatario control sobre si aparece en su perfil. El problema que aborda es que cualquier afirmación sobre una persona en Nostr es de otro modo solo una nota: no hay estructura que diga quién emitió una reclamación, cómo se llama, cómo se ve, o si el sujeto la aceptó. Las insignias dan a esa reclamación tres eventos firmados separados con tres intenciones de autor separadas codificadas en ellos.
La mecánica se construye a partir de una definición direccionable, un premio y una lista de visualización. Una definición de insignia es un evento kind 30009 publicado por el emisor, direccionable mediante su etiqueta d, de modo que el emisor puede revisar después las etiquetas name, description, image y thumb de la insignia sin cambiar el identificador al que apunta cualquier otra cosa. El premio es un evento kind 8 publicado por el mismo emisor, llevando una etiqueta a con la coordenada 30009:<issuer-pubkey>:<d-identifier> de la definición y una o más etiquetas p nombrando destinatarios. La lista de visualización es un evento kind 30008 publicado por el destinatario con el valor fijo d profile_badges, listando pares de etiquetas a y e donde la etiqueta a es la coordenada de definición y la etiqueta e es el evento de premio concreto. Esos pares están ordenados y se leen como pares: una etiqueta a cuyo premio coincidente falta, o una etiqueta e cuya definición coincidente falta, se ignora, así que una insignia referenciada a medias no se renderiza en silencio.
Los compromisos de diseño son visibles en lo que la especificación se niega a hacer. No hay mecanismo de revocación ni caducidad, así que un premio es una declaración permanente del emisor sobre un momento en el tiempo, y un emisor que cambia de opinión solo puede cambiar la definición a la que apunta el premio. No hay transferencia, así que una insignia no circula como token. No hay noción de registro de emisores de confianza, lo que empuja toda la pregunta de confianza al cliente y al lector: una insignia vale exactamente lo que la clave pública del emisor vale para quien la mira. La especificación también concede a los clientes libertad para mostrar menos insignias de las que listó el destinatario y elegir qué tamaño de imagen renderizar, lo que evita que un perfil se convierta en un muro de gráficos elegidos enteramente por terceros.
La especificación adyacente más cercana es NIP-51, la especificación de listas, y comparar las dos muestra por qué las insignias necesitan tres eventos en lugar de uno. Una lista es un solo autor curando referencias; el autor de la lista es el autor de la reclamación. Una insignia divide la autoría por la mitad, con el emisor firmando que ocurrió el premio y el destinatario firmando que acepta su visualización. Ninguna parte puede producir sola el resultado visible, lo que separa una insignia de una etiqueta autoaplicada.
Un premio kind 8 en vivo recuperado de nos.lol y relay.primal.net esta semana:
{
"id": "08504dec368939bd63849a349cab83dea0ac199a852129dbf68cf35fe5c64e96",
"pubkey": "bef514bd58c8ceea4beb9e6b84a8d983935f7be26f49e14df68098f1ba64156e",
"created_at": 1787051248,
"kind": 8,
"tags": [
["a", "30009:bef514bd58c8ceea4beb9e6b84a8d983935f7be26f49e14df68098f1ba64156e:blocks_orange_league"],
["p", "92dfa05d915196a7a09152fa3f57871debfd422e1d278ac5af266a70c3350b1f", "wss://relay.damus.io"]
],
"content": "Badge awarded!",
"sig": "5bf0218dfec5e56b47339b0b4b992cceedd2e18798fb3d47cafea51850c00827f66251e4a3e08190370e04a5e1d4d092eeb441141b7219acdd18b80290a022f8"
}
Las implementaciones actuales cubren emisión, visualización y lectura. Divine Mobile 1.0.20 acuña y otorga una insignia dentro de la app y explica una insignia ganada cuando un lector la toca, Nostter PR #2281 actualiza el manejo de insignias de perfil en un cliente web, y Amethyst publica eventos de premio llevando su propia etiqueta de cliente, uno de los cuales aparece en datos de relay junto al ejemplo anterior.
Comentarios (NIP-22)
NIP-22, definido por su especificación principal, proporciona un evento de comentario general para responder a cosas que no son notas de texto corto. El hilado de notas cortas ya tenía NIP-10 (convenciones de etiquetas de respuesta), cuyas convenciones de etiquetas crecieron alrededor de kind 1 y sus cadenas de respuesta. NIP-22 existe porque un vídeo, un artículo, un evento de calendario, una página wiki o una URL necesita una estructura de respuesta que identifique qué tipo de cosa se está respondiendo, y que funcione cuando el objetivo es direccionable, o es un recurso externo sin evento Nostr alguno.
La mecánica gira en torno a una distinción de mayúsculas. Un comentario es un evento kind 1111 que lleva dos conjuntos de etiquetas: etiquetas en mayúsculas describen la raíz de la discusión y etiquetas en minúsculas describen el padre inmediato. E, A e I nombran un evento raíz, una coordenada direccionable raíz o un identificador externo raíz, K nombra el kind de la raíz, y P nombra al autor de la raíz. Las variantes en minúsculas e, a, i, k y p nombran los mismos hechos sobre el padre, que es la raíz misma para un comentario de nivel superior y otro comentario kind 1111 para una respuesta anidada. Separarlas significa que un cliente puede obtener toda una discusión con un filtro sobre las etiquetas raíz en mayúsculas, sin recorrer la cadena de respuestas, mientras renderiza correctamente el anidamiento desde las etiquetas padre en minúsculas. Las variantes I e i llevan identificadores externos en el formato NIP-73 (referencias de contenido externo), lo que permite que un hilo de comentarios se adjunte a una página web, un episodio de pódcast o un libro.
Los compromisos son sobre todo lo que NIP-22 declina absorber. La especificación indica que los comentarios no deben usarse para responder a notas kind 1, lo que evita que dos modelos de hilado compitan sobre los mismos objetos y deja NIP-10 donde ya funciona. El anidamiento está permitido pero la raíz permanece fija, así que un hilo profundo nunca pierde su ancla aunque falten eventos intermedios. Las etiquetas de kind son la parte que soporta la carga: un cliente que obtiene un comentario sin su objetivo aún puede decir a qué se enfrenta desde K y k, y decidir si puede renderizar ese kind. Lo que la especificación no proporciona es ningún modelo de orden o moderación, así que el orden de visualización, colapso y ocultación son enteramente política del cliente.
Comparado con NIP-10, la diferencia está en el tipado. NIP-10 asume que el objetivo es una nota y codifica posición en un hilo; NIP-22 codifica explícitamente la identidad y el kind del objetivo y no asume nada más sobre él. Ese tipado explícito es por qué las propuestas más recientes de este número recurren a kind 1111: un comentario ya lleva una declaración legible por máquina sobre a qué está adjunto.
Un comentario kind 1111 en vivo recuperado de nos.lol y relay.primal.net esta semana, respondiendo a otro comentario bajo un vídeo:
{
"id": "c8d335f8bfea58ecd1a943d6000fb2045f4bddf4a36c67df53eb661671f7ab45",
"pubkey": "3e911baba55ae247339cf805dd6ff49ad2cd6bee84ac44e088ce66450c49104f",
"created_at": 1787062681,
"kind": 1111,
"tags": [
["E", "1c492f2bac17b79d66934a340fa43d8d30d0aea4c9fa329346c05573ef912d70", "", "482d024b8acfde50e7429e5ac561d764f3a53a8b4fb0b6975369d9f0926ef839"],
["A", "34236:482d024b8acfde50e7429e5ac561d764f3a53a8b4fb0b6975369d9f0926ef839:e64ba9ea157b1a315caff51dbca656ed73ce817d4494e3966adf24055a86f5c5", ""],
["K", "34236"],
["P", "482d024b8acfde50e7429e5ac561d764f3a53a8b4fb0b6975369d9f0926ef839"],
["e", "7a14723b9ef999e74b1757a0fb74942cb6c121138d4ddafe096a57a67ed0a442", "", "8b69e548402afa997343d73e8088224a440f256350f6257b61acc4bb1fa4af4f"],
["k", "1111"],
["p", "8b69e548402afa997343d73e8088224a440f256350f6257b61acc4bb1fa4af4f"],
["client", "Divine", "31990:d95aa8fc0eff8e488952495b8064991d27fb96ed8652f12cdedc5a4e8b5ae540:divine-mobile", "wss://relay.divine.video"]
],
"content": "niiice",
"sig": "a5517fdea07647efa7ab1730fbea8df882690bba667e93ea5aeba4a73be6a49af1ee17c045535483650caf41dbbcb0897d5803fa39b59f395fd6f9bb193bb789"
}
Las etiquetas en mayúsculas guardan el vídeo y su autor mientras las e y k en minúsculas apuntan al comentario padre, que es la forma que describe la especificación. Las implementaciones que leen y escriben kind 1111 incluyen Divine Mobile, cuya etiqueta de cliente aparece en el evento anterior, Amethyst, cuyos comentarios aparecen en los mismos resultados de relay, y nostrord, que renderiza publicaciones de hilo como publicaciones de foro esta semana. El formato de parche propuesto en NIPs PR #2438 se construye sobre el mismo kind.
Envía un DM NIP-17 (mensajes directos privados) para compartir un proyecto o una noticia a través del proyecto Nostr Compass.