Nostr WoT

Documentação

Tudo que você precisa para integrar Web of Trust em seu aplicativo.

API da extensão

A extensão expõe window.nostr para identidade, assinatura de eventos e criptografia de mensagens NIP-04/NIP-44.

Instale a extensão, selecione uma conta e conecte seu site quando solicitado. Assinatura e criptografia exigem uma conta capaz de assinar e podem pedir o desbloqueio do cofre. Ler uma chave pública conhecida não exige desbloqueá-lo.

Configuração

Verifique se o método necessário existe antes de chamá-lo. A presença do provedor não significa que o site está conectado ou que uma solicitação foi autorizada.

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 assinatura NIP-07

A extensão implementa a API de assinatura NIP-07 por meio de window.nostr.

getPublicKey()

Retorna a chave pública hexadecimal da conta ativa. Exige conexão do site e acesso à identidade.

Retorno

Promise<string>

Exemplo

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

signEvent(event)

Assina o evento e acrescenta id, pubkey e sig. Forneça created_at; o assinador preserva esse horário. Se fornecer pubkey, ela deve corresponder à conta ativa. Assinar não publica o evento.

Parâmetros

NomeTipoDescrição
eventUnsignedEventEvento com kind, content, tags e created_at (tempo Unix em segundos)

Retorno

Promise<SignedEvent>

Exemplo

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)

Criptografa uma mensagem com NIP-04, o formato antigo de criptografia de mensagens diretas.

Parâmetros

NomeTipoDescrição
pubkeystringChave pública do destinatário com 64 caracteres hexadecimais
plaintextstringMensagem a criptografar

Retorno

Promise<string>

Exemplo

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

nip04.decrypt(pubkey, ciphertext)

Descriptografa uma mensagem NIP-04.

Parâmetros

NomeTipoDescrição
pubkeystringChave pública do remetente com 64 caracteres hexadecimais
ciphertextstringTexto da mensagem criptografada

Retorno

Promise<string>

Exemplo

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

nip44.encrypt(pubkey, plaintext)

Criptografa uma mensagem com NIP-44. Este exemplo usa a chamada padrão com dois argumentos.

Parâmetros

NomeTipoDescrição
pubkeystringChave pública do destinatário com 64 caracteres hexadecimais
plaintextstringMensagem a criptografar

Retorno

Promise<string>

Exemplo

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

nip44.decrypt(pubkey, ciphertext)

Descriptografa uma mensagem NIP-44.

Parâmetros

NomeTipoDescrição
pubkeystringChave pública do remetente com 64 caracteres hexadecimais
ciphertextstringTexto da mensagem criptografada

Retorno

Promise<string>

Exemplo

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

getRelays()

Retorna os URLs dos relays configurados na extensão. Cada entrada tem read: true e write: true. Este método não consulta as políticas de relays NIP-65 da conta e pode retornar um objeto vazio.

Retorno

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

Exemplo

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

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

Conexão, permissões e erros

As chamadas retornam promessas e podem falhar se o usuário recusar, o site estiver desconectado, o acesso à identidade estiver desativado ou o tempo se esgotar. Contas somente leitura não podem assinar nem criptografar.

Uma troca de conta pode invalidar uma solicitação pendente. As chamadas da página expiram após 120 segundos, incluindo a espera por conexão, permissão ou desbloqueio. Trate os erros e permita tentar novamente; as mensagens de erro não são códigos estáveis para processamento 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 };
  }
}

Use o SDK para consultar o grafo de seguidores e a API WoT Oracle para consultar silenciamentos públicos. Essas informações ficam separadas da distância no grafo e não geram uma pontuação de confiança combinada. A extensão fornece identidade e assinatura.