Nostr WoT

Documentación

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

API de la extensión

La extensión expone window.nostr para identidad, firma de eventos y cifrado de mensajes NIP-04/NIP-44.

Instala la extensión, selecciona una cuenta y conecta tu sitio cuando se solicite. La firma y el cifrado requieren una cuenta capaz de firmar y pueden pedir que desbloquees la bóveda. Leer una clave pública conocida no requiere desbloquearla.

Configuración

Comprueba que el método que necesitas existe antes de llamarlo. La presencia del proveedor no significa que el sitio esté conectado ni que una solicitud esté aprobada.

javascript
// Feature detection
function hasNostr() {
  return typeof window !== "undefined" &&
         typeof window.nostr?.getPublicKey === "function";
}

// Wait for the extension to load
async function waitForNostr(timeout = 3000) {
  const start = Date.now();
  while (!hasNostr() && Date.now() - start < timeout) {
    await new Promise(r => setTimeout(r, 100));
  }
  return hasNostr();
}

API de firma NIP-07

La extensión implementa la API de firma NIP-07 mediante window.nostr.

getPublicKey()

Devuelve la clave pública hexadecimal de la cuenta activa. Requiere conectar el sitio y permitir el acceso a la identidad.

Devuelve

Promise<string>

Ejemplo

javascript
const pubkey = await window.nostr.getPublicKey();
console.log(pubkey); // "3bf0c63f..."

signEvent(event)

Firma el evento y añade id, pubkey y sig. Debes proporcionar created_at; el firmante conserva esa fecha. Si incluyes pubkey, debe coincidir con la cuenta activa. Firmar no publica el evento.

Parámetros

NombreTipoDescripción
eventUnsignedEventEvento con kind, content, tags y created_at (tiempo Unix en segundos)

Devuelve

Promise<SignedEvent>

Ejemplo

javascript
const signed = await window.nostr.signEvent({
  kind: 1,
  content: "Hello Nostr!",
  tags: [],
  created_at: Math.floor(Date.now() / 1000),
});
console.log(signed.sig); // schnorr signature

nip04.encrypt(pubkey, plaintext)

Cifra un mensaje mediante NIP-04, el formato antiguo de cifrado de mensajes directos.

Parámetros

NombreTipoDescripción
pubkeystringClave pública del destinatario, con 64 caracteres hexadecimales
plaintextstringMensaje que se cifrará

Devuelve

Promise<string>

Ejemplo

javascript
const encrypted = await window.nostr.nip04.encrypt(
  recipientPubkey,
  "Secret message"
);

nip04.decrypt(pubkey, ciphertext)

Descifra un mensaje NIP-04.

Parámetros

NombreTipoDescripción
pubkeystringClave pública del remitente, con 64 caracteres hexadecimales
ciphertextstringCadena del mensaje cifrado

Devuelve

Promise<string>

Ejemplo

javascript
const plaintext = await window.nostr.nip04.decrypt(
  senderPubkey,
  ciphertext
);
console.log(plaintext); // "Secret message"

nip44.encrypt(pubkey, plaintext)

Cifra un mensaje mediante NIP-44. Este ejemplo usa la llamada estándar de dos argumentos.

Parámetros

NombreTipoDescripción
pubkeystringClave pública del destinatario, con 64 caracteres hexadecimales
plaintextstringMensaje que se cifrará

Devuelve

Promise<string>

Ejemplo

javascript
const encrypted = await window.nostr.nip44.encrypt(
  recipientPubkey,
  "Secret message"
);

nip44.decrypt(pubkey, ciphertext)

Descifra un mensaje NIP-44.

Parámetros

NombreTipoDescripción
pubkeystringClave pública del remitente, con 64 caracteres hexadecimales
ciphertextstringCadena del mensaje cifrado

Devuelve

Promise<string>

Ejemplo

javascript
const plaintext = await window.nostr.nip44.decrypt(
  senderPubkey,
  ciphertext
);
console.log(plaintext); // "Secret message"

getRelays()

Devuelve las URL de los relés configurados en la extensión. Cada entrada tiene read: true y write: true. Este método no consulta las políticas de relés NIP-65 de la cuenta y puede devolver un objeto vacío.

Devuelve

Promise<Record<string, { read: boolean; write: boolean }>>

Ejemplo

javascript
const relays = await window.nostr.getRelays();

// {
//   "wss://relay.damus.io": { read: true, write: true },
//   "wss://nos.lol": { read: true, write: true }
// }

Conexión, permisos y errores

Las llamadas devuelven promesas y pueden rechazarse si el usuario no las autoriza, el sitio está desconectado, el acceso a la identidad está desactivado o se agota el tiempo. Las cuentas de solo lectura no pueden firmar ni cifrar.

Cambiar de cuenta puede invalidar una solicitud pendiente. Las llamadas desde la página caducan tras 120 segundos, incluida la espera de conexión, permiso o desbloqueo. Captura los errores y permite reintentar; los mensajes de error no son códigos estables para procesamiento automático.

javascript
async function signNote(content) {
  const provider = window.nostr;
  if (typeof provider?.getPublicKey !== "function" ||
      typeof provider?.signEvent !== "function") {
    return { ok: false, reason: "provider-unavailable" };
  }

  try {
    const pubkey = await provider.getPublicKey();
    if (!pubkey) return { ok: false, reason: "no-active-account" };

    const event = await provider.signEvent({
      pubkey,
      kind: 1,
      content,
      tags: [],
      created_at: Math.floor(Date.now() / 1000),
    });
    return { ok: true, event };
  } catch (error) {
    return { ok: false, reason: "request-failed", error };
  }
}

Usa el SDK para consultar el grafo de seguimientos y la API de WoT Oracle para obtener información sobre silenciamientos públicos. Esta información se presenta por separado de la distancia de seguimiento y no genera una puntuación de confianza combinada. La extensión proporciona identidad y firma.