Nostr WoT
NostrNIPTooling

nak 0.21.0 liest Relay-Listen und löst Petname-Pfade auf

Die Release-Notes sind leer, also ist der Diff der einzige Bericht darüber. Zwei Ergänzungen fallen auf: ein neuer Unterbefehl für NIP-65-Relay-Listen und die Auflösung von Petname-Pfaden, die im gemeinsamen Parser für öffentliche Schlüssel sitzt und nicht in einem einzelnen Befehl.

Nostr WoT Newsroom

Artikel5 Min. Lesezeit

Von der Nostr WoT Redaktion aus den zitierten Primärquellen zusammengestellt und automatisch ohne individuelle menschliche Prüfung veröffentlicht.

nak 0.21.0 liest Relay-Listen und löst Petname-Pfade auf

nak, das Kommandozeilenwerkzeug für Nostr, hat am 3. Oktober 2026 die v0.21.0 getaggt. Der Text der Veröffentlichung ist leer, daher sind die siebzehn Commits seit v0.20.7 der einzige Bericht darüber, was sich geändert hat. Zwei davon ergänzen Fähigkeiten, statt Verhalten zu korrigieren, und beide setzen auf Spezifikationen auf, über die diese Seite schon berichtet hat.

Ein Befehl für NIP-65-Relay-Listen

55707c26 ergänzt relays.go, eine Datei mit 58 Zeilen, die einen neuen Unterbefehl der obersten Ebene registriert. Seine Nutzungszeile nennt den Umfang: prints the nip65 relays for a given pubkey, one relay per line.

Er nimmt einen öffentlichen Schlüssel als Argument oder über die Standardeingabe und schreibt eine Relay-URL pro Zeile. Zwei Flags engen die Ausgabe ein, jedes mit einem Alias, der die andere Hälfte des NIP-65-Vokabulars benennt:

text
--inbox, --read     only print relays marked as inbox/read
--outbox, --write   only print relays marked as outbox/write

Die Filterlogik lohnt eine wörtliche Lesung, denn der kombinierte Fall ist keine Vereinigung. Beide Flags zusammen verlangen beide Markierungen am selben Relay:

go
if wantInbox && wantOutbox {
    if !(rl.Inbox && rl.Outbox) {
        continue
    }
}

--inbox --outbox gibt also nur die Relays aus, die beide Richtungen bedienen, was unter NIP-65 einem r-Tag ohne Markierung entspricht, während keines der Flags die vollständige Liste ausgibt. Gemeinsam verengen die zwei Flags die Menge, statt sie zu erweitern, und das zählt, sobald die Ausgabe in einen Veröffentlichungsschritt läuft.

Die Richtungsnamen entsprechen den Rollen, die im heute ebenfalls veröffentlichten Leitfaden zum NIP-65-Routing beschrieben sind: von den Ausgangs-Relays eines Autors werden seine Events abgeholt, und an die Eingangs-Relays eines Empfängers werden Events ausgeliefert, die ihn erwähnen. Der Befehl macht beide Ziele skriptfähig, ohne ein Event vom kind 10002 von Hand zu zerlegen.

Petname-Pfade, im gemeinsamen Parser

Die Petname-Pfade aus NIP-02 kommen in zwei Stufen, und die zweite korrigiert die erste. Es ist die Funktion, die NIP-02 in der am 20. September berichteten Überarbeitung erhielt und die drei Tage später in der Folgeänderung auf ASCII beschränkt wurde.

4011cba5 ergänzt keinen Befehl. Es ändert den gemeinsamen Parser: parsePubKey erhält ein zweites Argument, einen öffentlichen Schlüssel, von dem aus aufgelöst wird, und leitet alles, was mit einer Tilde beginnt, an ein neues resolvePetnamePath weiter.

go
func parsePubKey(value string, from nostr.PubKey) (nostr.PubKey, error) {
	value = strings.TrimPrefix(value, "nostr:")

	if strings.HasPrefix(value, "~") {
		return resolvePetnamePath(value, from)
	}

Diese Hilfsfunktion ruft sys.ResolvePetnamePath mit einem Zeitlimit von fünf Sekunden auf. Ihr Dokumentationskommentar nennt den Mechanismus und die gemischte Form, die NIP-02 erlaubt: der Pfad ~erin/david/frank läuft die Folgeliste jedes Namens in der Kette ab, und der erste Name darf stattdessen ein NIP-05-Identifikator sein, wie in [email protected]/david/frank. Da die darunterliegende Profilsuche NIP-05-Fehler verbirgt, wird eine fehlgeschlagene Auflösung erneut gegen nip05.QueryIdentifier geprüft, damit ein DNS- oder HTTP-Problem als solches gemeldet wird und nicht als unauflösbarer Petname. Der Commit aktualisiert jede Aufrufstelle und ergänzt 239 Zeilen Tests.

Was diese Stufe offen lässt, ist der Schlüssel, von dem ein relativer Pfad ausgeht. Die am 25. September integrierte Pull Request #220 ergänzt petname_cli.go und eine Hülle parsePubKeyForCommand, die die Wurzel einordnet:

go
absolute := hexErr == nil || nip05.IsValidIdentifier(parts[0]) ||
    (nip19Err == nil && (prefix == "npub" || prefix == "nprofile"))

Ein Pfad, der in einem hexadezimalen öffentlichen Schlüssel, einem gültigen NIP-05-Identifikator oder einem npub oder nprofile wurzelt, gilt als absolut, und ein Kommentar hält fest, warum der Fall getrennt wird: Absolute roots must also work without access to a signing key. Nur ein relativer Pfad ruft gatherKeyerFromArguments auf und nimmt den öffentlichen Schlüssel dieses Signierers als Ausgangspunkt. Nach außen zu lesen, ausgehend von jemandem, den man benennen kann, braucht also keinen Schlüssel, ein Pfad ausgehend von den eigenen Follows dagegen schon.

Dieselbe Pull Request behebt ein Problem mit der Argumentreihenfolge. Ein Aufruf in init wendet deferPetnameFlags auf den gesamten Befehlsbaum an und ersetzt jedes Flag, das öffentliche Schlüssel trägt, durch eine Hülle, die die rohe Zeichenkette aufbewahrt und sie erst auflöst, wenn alle Flags gelesen sind. Der Kommentar nennt den Grund: ein Signierer-Flag wie --sec kann in der Kommandozeile nach dem Petname-Flag stehen, und die Auflösung braucht den Signierer. Sie ergänzt weitere 169 Zeilen Tests.

Vervollständigung und drei kleinere Korrekturen

5f28b21c setzt EnableShellCompletion: true am Wurzelbefehl, was nak completion bash, zsh und fish verfügbar macht. Das README erhält die drei Installationspfade für Shells, deren Paket das nicht selbst einrichtet.

Drei Verhaltenskorrekturen sind eng umgrenzt, schließen aber jeweils einen Fall, in dem das Werkzeug etwas Unbrauchbares tat, statt ein Problem zu melden:

  • 30551476 ergänzt --github bei nak event, und die Nutzungszeile nennt den Grund: treat empty stdin as no stdin at all, as GitHub Actions always opens it. In dieser Umgebung war eine stets offene, aber leere Standardeingabe nicht von einer Eingabe über eine Pipe zu unterscheiden.
  • nak key encrypt mit einem einzigen Argument scheitert nun mit no password given or key piped on stdin, wenn die Standardeingabe keine Pipe ist, statt dieses einzelne Argument als Passwort ohne zugehörigen Schlüssel zu lesen.
  • blossom entfernt Required: true vom Flag --server, sodass der Server je Unterbefehl angegeben werden kann, und sein Fehlen liefert jetzt no server specified. blossom upload erhält --auto, was die vom aktuellen Nutzer angekündigten Medienserver auflöst. nsite download nimmt neben einer Website-URL auch einen nevent1- oder naddr1-Zeiger und holt die Daten von den Schreib-Relays des Autors sowie über die Hinweise, die der Zeiger mitbringt.

Was das in der Praxis bedeutet

Beide Ergänzungen nehmen allen, die gegen Nostr skripten, je einen handgemachten Schritt ab. Die Frage, wo veröffentlicht und wo gelesen wird, verlangt kein Abholen und Zerlegen eines Events vom kind 10002 mehr, und ein Follow-Pfad lässt sich dort schreiben, wo früher eine hexadezimale Zeichenkette aus 64 Zeichen stand. Keine der beiden Änderungen berührt eine Spezifikation: hier zieht ein Werkzeug mit NIP-02 und NIP-65 in ihrer bestehenden Form nach. Die Regel zur absoluten Wurzel ist das Detail, das man behalten sollte, denn ein Petname-Pfad, der von den eigenen Follows ausgeht, wird einen Schlüssel verlangen.

Quellen

Jede Aussage in diesem Beitrag verlinkt auf eine Primärquelle.

  1. nak v0.21.0 — fiatjaf/nak (3. Oktober 2026)
  2. Vergleich v0.20.7...v0.21.0 — fiatjaf/nak (3. Oktober 2026)
  3. nak relays — fiatjaf/nak (1. Oktober 2026)
  4. petname support in parsePubKey() — fiatjaf/nak (17. September 2026)
  5. Pull request #220: Resolve relative petnames using the selected signer — fiatjaf/nak (25. September 2026)
  6. enable shell completion generation — fiatjaf/nak (1. Oktober 2026)
  7. Correct nak event behaviour if 0 lines received from an open stdin — fiatjaf/nak (25. September 2026)

Bleib auf dem Laufenden

Erhalte Neuigkeiten zu veröffentlichten Nostr-WoT-Versionen, neuen Funktionen und Integrationen.

Du erhältst den Newsletter auf Deutsch.

Wir speichern deine E-Mail-Adresse und bevorzugte Sprache, um dir den Newsletter zu senden.

Newsletter