Nostr WoT

Documentación

Todo lo que necesitas para integrar Web of Trust en tu aplicación.

API del Oracle

Versión 0.3.0: distancia de seguimiento dirigida e indicios públicos de silenciamiento separados mediante HTTP. No requiere extensión.

Servidor público y formato de solicitudes

URL base: https://wot-oracle.mappingbitcoin.com. El Oracle no requiere una clave de API.

Envía claves públicas como cadenas hexadecimales completas de 64 caracteres en minúsculas, no npubs. Los ejemplos usan claves públicas sintéticas para ilustrar la estructura de las respuestas; los resultados de tu grafo serán distintos. Las solicitudes POST usan Content-Type: application/json.

El endpoint raíz GET / enumera la versión del servicio, la documentación y los endpoints disponibles. Para tu propia instancia, consulta la guía de alojamiento propio.

Las distancias usan aristas de seguimiento dirigidas de kind-3. Las listas públicas de silenciamiento kind-10000 son observaciones separadas. El Oracle no las combina en una puntuación de confianza ni elimina las cuentas silenciadas de las rutas de seguimiento.

Endpoints

GET/health

Actividad del proceso y versión publicada.

json
{
  "status": "healthy",
  "version": "0.3.0"
}
terminal
$curl "https://wot-oracle.mappingbitcoin.com/health"

Un proceso saludable puede seguir esperando eventos de relés o no poder guardar las actualizaciones. Usa /ready para comprobar la preparación de la ingesta.

GET/ready

Estado de la ingesta: HTTP 200 si está lista; HTTP 503 en caso contrario.

La preparación requiere una ingesta activa, ausencia de fallos actuales de base de datos y un evento de seguimiento o silenciamiento recibido en los últimos cinco minutos. Por ello, un relé privado sin actividad puede producir un 503 aunque el proceso esté operativo. Ejemplo mientras se espera el primer evento:

json
{
  "running": true,
  "ready": false,
  "last_event_received_at": 0,
  "last_persisted_at": 0,
  "persisted_events": 0,
  "lagged_notifications": 0,
  "persistence_errors": 0,
  "coverage": "configured_relays_only"
}

Las marcas de tiempo son segundos Unix; cero significa que aún no se ha observado. persisted_events cuenta las actualizaciones de autor aceptadas que se escribieron en el almacenamiento tras consolidar los lotes. lagged_notifications y persistence_errors muestran problemas de ingesta.

GET/stats

Recuentos del grafo indexado, ajustes de caché, métricas de bloqueos y estado de la ingesta.

json
{
  "node_count": 3,
  "edge_count": 2,
  "nodes_with_follows": 2,
  "mute_edge_count": 0,
  "nodes_with_mute_lists": 1,
  "sync": {
    "running": true,
    "ready": false,
    "last_event_received_at": 0,
    "last_persisted_at": 0,
    "persisted_events": 0,
    "lagged_notifications": 0,
    "persistence_errors": 0,
    "coverage": "configured_relays_only"
  },
  "cache": {
    "size": 0,
    "capacity": 100000,
    "ttl_secs": 300
  },
  "locks": {
    "write_lock_count": 0,
    "write_lock_avg_us": 0,
    "write_lock_max_us": 0,
    "read_lock_count": 0,
    "read_lock_avg_us": 0,
    "read_lock_max_us": 0
  }
}

Los recuentos y ajustes anteriores son ilustrativos. edge_count cuenta las aristas de seguimiento; mute_edge_count cuenta las aristas públicas de silenciamiento de claves públicas. nodes_with_mute_lists incluye listas conocidas sin entradas públicas de claves públicas. Los tiempos de bloqueo se expresan en microsegundos. El objeto sync tiene los mismos campos que /ready.

GET/distance

Distancia de seguimiento dirigida más corta entre dos claves públicas.

  • from y to: claves públicas de origen y destino obligatorias.
  • max_hops: 1–5, valor predeterminado 3.
  • include_bridges: booleano, false por defecto. Incluye los nodos de encuentro de la búsqueda cuando están disponibles.
  • bypass_cache: booleano, false por defecto. Recalcula a partir del grafo indexado actual; no obtiene nuevos datos de los relés.
json
{
  "from": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
  "to": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
  "hops": 2,
  "path_count": 1,
  "mutual_follow": false
}

hops vale cero para la distancia a uno mismo y uno para un seguimiento directo. Un valor null significa que no se encontró una ruta dentro de la profundidad solicitada en el grafo indexado. No demuestra que no exista una conexión en otro lugar de Nostr.

path_count cuenta las rutas dirigidas más cortas, incluso cuando se omiten los puentes; el recuento se satura en el máximo entero sin signo de 64 bits. mutual_follow indica un seguimiento directo en ambas direcciones. El campo opcional bridges contiene nodos de encuentro de la búsqueda, no una ruta completa ni una prueba de rutas disjuntas.

terminal
$curl "https://wot-oracle.mappingbitcoin.com/distance?from=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&to=bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb&max_hops=3"

POST/distance/batch

Consulta hasta 100 destinos desde un origen, conservando el orden de los destinos y los duplicados.

Campos JSON obligatorios: from y targets. Los campos opcionales max_hops, include_bridges y bypass_cache usan los mismos valores predeterminados que /distance.

Solicitud

json
{
  "from": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
  "targets": [
    "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
  ],
  "max_hops": 3
}

Respuesta

json
{
  "from": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
  "results": [
    {
      "from": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
      "to": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
      "hops": 2,
      "path_count": 1,
      "mutual_follow": false
    }
  ]
}

Cada resultado incluye tanto from como to.

GET/path

Devuelve las claves públicas intermedias de una ruta dirigida de seguimiento más corta.

from y to son obligatorios; max_hops es opcional (1–5, 3 por defecto).

json
{
  "from": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
  "to": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
  "path": [
    "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
  ]
}

El ejemplo representa dos aristas de seguimiento: del origen al puente y del puente al destino. El origen y el destino se excluyen de path. Las rutas hacia uno mismo y las de seguimiento directo devuelven un array vacío; si no existe ruta dentro de la profundidad solicitada, se devuelve null. Esta respuesta no contiene un campo hops.

GET/follows

Pagina la lista de seguimiento actualmente indexada de una clave pública.

pubkey es obligatorio; offset (0 por defecto) y limit (500 por defecto, máximo 5000) son opcionales. total es el tamaño completo de la lista indexada, independientemente del tamaño de página.

json
{
  "pubkey": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
  "follows": [
    "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
  ],
  "total": 1
}

Una clave pública desconocida devuelve una lista vacía y total: 0.

GET/common-follows

Devuelve las claves públicas seguidas directamente por ambas cuentas.

Parámetros obligatorios: from y to.

json
{
  "from": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
  "to": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
  "common_follows": [
    "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
  ]
}
terminal
$curl "https://wot-oracle.mappingbitcoin.com/common-follows?from=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa&to=bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"

GET/mutes

Pagina las entradas públicas de claves públicas de una lista de silenciamiento kind-10000 indexada.

pubkey es obligatorio; offset (0 por defecto) y limit (500 por defecto, máximo 5000) son opcionales. total es el tamaño completo de la lista indexada, independientemente del tamaño de página.

json
{
  "pubkey": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
  "mutes": [],
  "total": 0,
  "public_list_known": true
}

public_list_known: false significa que no se indexó ningún evento de lista de silenciamiento para esta clave pública. Un evento conocido puede no tener entradas públicas de claves públicas, como se muestra arriba. El Oracle no puede acceder a las entradas cifradas de silenciamiento; una lista pública conocida vacía puede contener entradas cifradas. Las etiquetas de silenciamiento de palabras, hashtags e hilos se excluyen de los indicios sobre claves públicas.

GET/trust

Devuelve la distancia de seguimiento junto con observaciones públicas de silenciamiento separadas.

  • from y to: claves públicas de origen y destino obligatorias.
  • max_hops: 1–5, valor predeterminado 3.
  • include_bridges: booleano, false por defecto. Incluye los nodos de encuentro de la búsqueda cuando están disponibles.
  • bypass_cache: booleano, false por defecto. Recalcula a partir del grafo indexado actual; no obtiene nuevos datos de los relés.
json
{
  "follow_distance": {
    "from": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
    "to": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
    "hops": 2,
    "path_count": 1,
    "mutual_follow": false
  },
  "public_mute_evidence": {
    "source_mutes_target": false,
    "target_mutes_source": false,
    "followed_muters": [
      "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
    ],
    "source_mute_list_known": true,
    "target_mute_list_known": false
  }
}

followed_muters enumera las cuentas seguidas directamente por el origen cuyas listas públicas indexadas de silenciamiento contienen al destino. Los dos booleanos de silenciamiento directo describen la relación entre origen y destino; los indicadores de lista conocida distinguen las listas ausentes de las listas públicas conocidas.

Los silenciamientos pueden expresar preferencias personales. La ausencia de indicios públicos no equivale a una aprobación. Los clientes deciden cómo usar estas observaciones: la respuesta no aplica ponderaciones, puntuaciones agregadas ni exclusiones automáticas. La distancia de seguimiento y los indicios de silenciamiento pueden leerse en instantes ligeramente distintos durante la ingesta.

Cobertura y actualidad

sync.coverage es configured_relays_only. Los resultados describen eventos indexados de los relés configurados en el servidor, sin garantía de cobertura global o completa. Las entradas de caché se invalidan cuando cambia la revisión del grafo. Ni la preparación ni omitir la caché garantizan que los relés hayan devuelto el evento más reciente.

La caché de perfiles kind-0, /profiles e include_profiles no están implementados en v0.3.0.

Límites y errores

Los endpoints de datos usan un depósito de tokens por IP configurado mediante RATE_LIMIT_PER_MINUTE. Los límites dependen del despliegue; las solicitudes pueden rechazarse después de una ráfaga incluso antes de que transcurra un minuto. Las rutas raíz, /health y /ready están exentas de este limitador. Los cuerpos de las solicitudes tienen un límite de 1 MiB. No supongas que todas las respuestas incluyen cabeceras de límite de solicitudes.

Los errores de validación y cálculo de la aplicación devuelven JSON con error y code:

json
{
  "error": "Invalid pubkey format",
  "code": "INVALID_PUBKEY"
}
  • 400: INVALID_PUBKEY, INVALID_MAX_HOPS o TOO_MANY_TARGETS.
  • 413: el cuerpo de la solicitud supera el límite de tamaño.
  • 429: se superó el límite de solicitudes por IP. Espera antes de reintentar; respeta el tiempo indicado para el reintento, si se proporciona.
  • 500: INTERNAL_ERROR.
  • 503: QUERY_BUSY cuando se agota la capacidad de consultas, o un estado de preparación con ready: false desde /ready.

Las cadenas de consulta mal formadas, el JSON mal formado y los rechazos del middleware pueden usar otro formato de cuerpo. Comprueba el estado HTTP antes de interpretar una respuesta como exitosa. Limita los reintentos y aumenta la espera ante una sobrecarga temporal.