Capítulo 6

Kinds y NIPs

Una tabla periódica de los kinds de eventos y las especificaciones que los definen.

¡Mismo sobre, distinto sello! Vamos a ordenar el correo por kind.

Un sobre, muchos sellos

Hasta ahora todos los eventos se han visto iguales: un id, una pubkey, una marca de tiempo, algunas etiquetas, algo de contenido y una firma. Una nota tipo tuit, tu perfil, un “me gusta”, una entrada de blog y un recibo de Lightning viajan todos en exactamente el mismo sobre.

Entonces, ¿cómo sabe una app qué es cada cosa? Por un campo diminuto: el kind. Es solo un número entero, como un sello en el sobre. 1 significa “nota de texto corta”, 0 significa “mi perfil”, 7 significa “reacción”, 30023 significa “artículo largo”. Eso es todo. Ni tipos de mensaje nuevos ni endpoints nuevos: Nostr crece inventando números nuevos.

Piensa en el kind como la sección de una biblioteca. Todos los libros (eventos) están encuadernados igual, pero la etiqueta del lomo le dice al bibliotecario (el relay) en qué estante ponerlo, y les dice a los lectores (los clientes) cómo mostrarlo.

La tabla periódica de los kinds

Los químicos ordenan los elementos según sus propiedades. Podemos hacer lo mismo con los kinds: el color de una casilla es su categoría de almacenamiento, que depende únicamente del rango del número. Explora un poco: cada casilla abre un evento de ejemplo real. Intenta visitar los cuatro colores.

La tabla periódica de los kinds

Cada casilla es un kind de evento. Filtra por categoría de almacenamiento o busca, y elige una casilla para ver un evento de ejemplo real.

Mostrar categorías

60 kinds mostrados

Exploraste 1 de 4 categorías

Regular Los relays guardan todos.

Reemplazable Los relays guardan solo el más reciente de cada autor.

Efímero Los relays los reenvían pero nunca los guardan.

Direccionable Los relays guardan el más reciente por autor y tag d.

Nota de texto corta

Kind 1

Regular

Una publicación de texto, como un tuit.

Qué hacen los relays
Los relays guardan todos. Rango: 1–2, 4–44, 1000–9999
Evento de ejemplo

Un evento firmado real de nuestro conjunto de ejemplos.

  { "id": "ea2e3eb8fe5e6cfbc202da21df546f68c6673e9a00c0aed61cffbac7aed9faf7" ,"pubkey": "a73883912a48c3551c1548fd454876d577126a61c76b5486c807bfec5869e183" ,"created_at": 1735686600 ,"kind": 1 , "tags": [  ] ,"content": "testing testing is this thing on" ,"sig": "82bc74fdbd5b113f257f4c8b2a6db64410ae897362bd42839fe9a34737d5ecb518a99f8517058ef8c2beadc222142e4d68f034e829edc9dd1b6bd13d2a139a7d"  } 
Pedirle este kind a un relay
["REQ","kinds-demo",{"kinds":[1],"limit":10}]

Bajo el capó: dónde se registran los kinds Mostrar detalles

No existe un servidor de registro central: la lista de kinds conocidos vive en el README del repositorio nostr-protocol/nips, junto al NIP que define cada uno. Los ejemplos de la tabla de arriba son eventos reales de nuestros ejemplos (con firmas verificadas) o plantillas firmadas en tu navegador con una clave de demostración pública y un auxRand fijo, así que los bytes son idénticos en cada visita.

import { kinds } from "nostr-tools";

kinds.ShortTextNote;            // 1
kinds.LongFormArticle;          // 30023
kinds.classifyKind(30023);      // "parameterized" (el nombre antiguo de nostr-tools para direccionable)
kinds.isReplaceableKind(10002); // true

Cuatro formas de guardarse

El número le dice a un relay qué debe conservar. NIP-01 divide la recta numérica en cuatro barrios:

  • Regular (1, 2, 4–44, 1000–9999): un diario. Se conserva cada página. Las notas, reacciones, reposts y recibos de zaps se acumulan para siempre (o hasta que el relay decida otra cosa).
  • Reemplazable (0, 3, 10000–19999): una pizarra. Cada persona tiene una por kind; al escribir una nueva se borra la anterior. Tu perfil (kind 0), tu lista de seguidos (kind 3) y tu lista de relays (kind 10002) funcionan así.
  • Efímero (20000–29999): una llamada telefónica. Los relays se lo pasan a quien esté escuchando en ese momento y luego lo olvidan. Perfecto para desafíos de inicio de sesión y la charla de los firmantes.
  • Direccionable (30000–39999): un conjunto de pizarras con etiqueta. Una por persona, por kind y por etiqueta d. Así puedes editar varios artículos largos de forma independiente.

Juega con él. Publica algunas versiones, cambia de categoría y luego prueba a reenviar una copia antigua:

Simulador de almacenamiento del relay

Publica varias versiones de un evento y observa qué guarda el relay en su estante.

Categoría a simular

Estante del relay 0 eventos guardados

El estante está vacío.

Suscriptores en vivo

Nadie ha recibido nada todavía.

¿Quién gana un empate?

En los eventos reemplazables y direccionables gana el created_at más reciente. Si dos versiones comparten exactamente el mismo segundo, los relays se quedan con la del id más bajo (la primera en orden alfabético), así que todos los relays terminan de acuerdo sobre el mismo ganador sin importar qué copia llegó primero.

Bajo el capó: las reglas de almacenamiento de NIP-01 Mostrar detalles

Las reglas exactas de NIP-01:

Categoría Rango El relay conserva
regular 1000 <= n < 10000 || 4 <= n < 45 || n == 1 || n == 2 todos los eventos
reemplazable 10000 <= n < 20000 || n == 0 || n == 3 el último por (pubkey, kind)
efímero 20000 <= n < 30000 nada (solo los reenvía)
direccionable 30000 <= n < 40000 el último por (pubkey, kind, d)

Los kinds 45–999 y 40000–65535 quedan fuera de todos los rangos: NIP-01 no dice nada sobre cómo guardarlos, y la mayoría de los relays los tratan como regulares. A un evento direccionable se le apunta con su dirección kind:pubkey:d, ya sea en una etiqueta a o codificada como naddr:

["a", "30023:e550c6e92808f358382b7b8c14345344f5ef9a299529834d1c26d57b6ace44cc:relays-explained", "wss://relay.alpha.example"]

Pedir “la versión actual” es un filtro normal, porque el relay solo guarda una:

["REQ", "article", { "kinds": [30023], "authors": ["e550c6…"], "#d": ["relays-explained"] }]

¿Quieres poner a prueba tu intuición? Escribe cualquier número y mira en qué barrio vive:

Clasificador de números de kind

Kind 30023: categoría Direccionable.

Los relays guardan el más reciente por autor y tag d.

Este lo conocemos: Artículo largo (NIP-23).

NIPs: cómo crece Nostr sin un jefe

¿Quién decide que 7 significa “reacción”? Nadie y todos. Un NIP (Nostr Implementation Possibility, “posibilidad de implementación de Nostr”) es un documento corto y público que describe una convención: qué kind usar, qué etiquetas, qué significa el contenido. Viven en un único repositorio de GitHub, pero funcionan más como recetas compartidas en una comida a la canasta que como leyes:

  1. Alguien tiene una idea. Una desarrolladora quiere encuestas, o calendarios, o mercados.
  2. Primero lo construye. Idealmente en un cliente y un relay reales, eligiendo un número de kind que nadie más use.
  3. Abre un pull request. La gente discute, simplifica y le busca los fallos en público.
  4. Se fusiona cuando es real. El README pide que un NIP esté implementado en al menos dos clientes y un relay (cuando aplique), que tenga sentido, que sea opcional y retrocompatible, y que no añada una segunda forma de hacer lo mismo.

El truco clave es la palabra opcional. Un cliente que no entiende el kind 31922 (un evento de calendario) simplemente lo ignora. No se rompe nada. Por eso Nostr puede crecer hacia los lados: microblogging, contenido largo, transmisiones en vivo, colaboración en código y wallets comparten los mismos relays y las mismas claves.

Los nombres de los NIPs no siempre son números

La mayoría de los NIPs tienen nombres decimales de dos dígitos (01, 57), pero los más nuevos pueden usar nombres con aspecto hexadecimal, como 7D (hilos) o C7 (chats). El número de kind y el número de NIP no tienen relación: el kind 7 se define en NIP-25, no en NIP-07.

Bajo el capó: NIPs que vale la pena leer Mostrar detalles

Buenos puntos de partida en el repositorio de NIPs:

  • NIP-01: el formato de los eventos, el kind 0 y las cuatro categorías de almacenamiento (el kind 1 se especifica en NIP-10)
  • NIP-02: lista de seguidos (kind 3)
  • NIP-23 (especificación): contenido largo (kind 30023, borradores 30024)
  • NIP-51: listas, estándar (10000+) y conjuntos (30000+)
  • NIP-65: metadatos de la lista de relays (kind 10002)
  • NIP-31: pon una etiqueta alt legible por humanos en los kinds personalizados, para que los clientes que no los entienden puedan mostrar algo. El README de NIPs ahora marca NIP-31 como no recomendado, pero una etiqueta alt en un kind personalizado sigue siendo una cortesía inofensiva
  • NIP-89: las apps anuncian qué kinds manejan (31990) y los usuarios recomiendan apps (31989)

¿Vas a inventar un kind privado para tu app? Elige un número sin usar en el rango adecuado para el comportamiento de almacenamiento que quieres, añade una etiqueta alt y documéntalo.

Comprobación rápida

Cambias tu foto de perfil tres veces. ¿Cuántos eventos de kind 0 tuyos conserva un relay que se porta bien?

Elige una respuesta

¿Qué kind te permite tener varias entradas de blog editables de forma independiente?

Elige una respuesta

Un cliente recibe un evento con un kind del que nunca ha oído hablar. ¿Qué debería hacer?

Elige una respuesta

Lo esencial

  • Todo evento tiene un kind: un número que dice qué es (una nota, un perfil, una reacción…).
  • El rango del número les dice a los relays cómo guardarlo: regular (guardar todos), reemplazable (guardar el último), efímero (no guardar ninguno), direccionable (guardar el último por etiqueta d).
  • En los eventos reemplazables y direccionables gana el created_at más reciente; en caso de empate, gana el id más bajo.
  • Los NIPs son las especificaciones abiertas de la comunidad. Un kind nuevo es solo un número más un NIP que lo explica.
  • Los clientes ignoran los kinds que no entienden, así que las funciones nuevas nunca rompen las apps viejas.