nmilat

module
v0.2.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 21, 2026 License: Unlicense

README

nmilat

CI Go Reference Go Report Card Go Version Go

nmilat is a Go SDK for building on the Nostr protocol. It handles the plumbing — event parsing, signing, verification, and 31 NIPs — so you can focus on what you're building.

Use it to:

  • Build a client or bot that reads, signs, and publishes Nostr events
  • Run your own relay with the embeddable engine: event storage, sessions, and profile search included
  • Talk to remote relays over WebSocket without hand-rolling the wire protocol

No CLI or UI code lives here — this module is a library only. The ncli application is built on top of it.

Install

go get github.com/ohstr/nmilat

Package overview

Implemented NIPs
  • nip01 — Core event, filter, and subscription types (the foundation every other package builds on)
  • nip04, nip44, nip49 — Encryption: direct messages, payloads, private keys
  • nip05 — NIP-05 identity verification
  • nip09 — Event deletion
  • nip11 — Relay information document
  • nip13 — Proof of work
  • nip16 — Event treatment (regular/replaceable/ephemeral kinds; folded into NIP-01 upstream)
  • nip17, nip59 — Private direct messages, gift wraps
  • nip19 — Bech32-encoded entities: npub, nsec, note, plus the TLV-based nprofile, nevent, and naddr
  • nip23 — Long-form content
  • nip26 — Event delegation
  • nip33 — Parameterized replaceable events (renamed "addressable events" and folded into NIP-01 upstream)
  • nip40 — Event expiration
  • nip42, nip98 — Relay/HTTP authentication
  • nip43 — Relay access metadata and requests
  • nip46 — Nostr Connect (remote signing)
  • nip47 — Wallet Connect (NWC): info/request/response/notification events, encryption negotiation, pairing URI
  • nip48 — Proxy tags
  • nip57 — Lightning zaps, plus AltZap (see below)
  • nip65 — Relay list metadata
  • nip77 — Negentropy sync
  • nip88 — Polls
  • nip90 — Data Vending Machines
  • nipAA — Agent Auth
  • nipB0 — Web bookmarks
  • nipB7 — Blossom media
  • nipOA — Owner Attestation
Relay engine and infrastructure
  • relay — Embeddable relay engine
  • relay/client — Relay client (WebSocket, NWC)
  • relay/migrations — Event store schema migrations
  • search — Profile search indexing/ranking
  • config — Embedded YAML config for search
  • wire — Relay wire-protocol packet types
  • utils — Shared event/key/logging helpers

NIP packages with relay-side concerns (NIP-47/48/57/65/88/90/B0/B7) stay dependency-free on their own; blank-import their relayreg subpackage to declare relay support, e.g. import _ "github.com/ohstr/nmilat/nip57/relayreg". See "Run a relay" below.

Quick start

Run a relay
package main

import (
	"log"
	"net/http"

	"github.com/ohstr/nmilat/nip11"
	"github.com/ohstr/nmilat/relay"

	// Blank-import the relayreg subpackage for every optional NIP this relay
	// should declare support for and auto-validate incoming events against.
	// Without these, relay.New still works — it just won't know about
	// zaps/polls/DVMs/etc. NIP-09/16/33/40/77 are always on (core to NIP-01
	// handling), and NIP-42/43/AA/26/50 turn on automatically from
	// SessionConfig — none of those need a relayreg import.
	_ "github.com/ohstr/nmilat/nip57/relayreg"
	_ "github.com/ohstr/nmilat/nip65/relayreg"
)

func main() {
	metadata := &nip11.Metadata{
		Name:       "my-relay",
		Limitation: nip11.Limitation{MaxLimit: 1000, MaxMessageLength: 1024 * 1024},
	}

	rl, err := relay.New("relay.db", metadata)
	if err != nil {
		log.Fatal(err)
	}
	defer rl.Close()

	log.Fatal(http.ListenAndServe(":8080", rl))
}

relay.New includes NIP-11 relay-info negotiation and starts profile verification, with search disabled. For storage tuning, a search service, or session options (CORS allowlist, NIP-26 delegation, ...), build the store and handler directly with relay.NewEventStore/relay.NewSessionHandler instead.

Connect with relayclient.Connect against ws://localhost:8080 (next example).

Read events from a relay

Connect, subscribe to a filter, and read events until EOSE. Relay input is untrusted, so always call Verify() before acting on an event:

package main

import (
	"context"
	"fmt"
	"net/url"

	"github.com/ohstr/nmilat/nip01"
	relayclient "github.com/ohstr/nmilat/relay/client"
)

func main() {
	filters := nip01.NewSubscriptionFilterGroup(nip01.NewFilter().WithKinds(1).WithLimit(10))

	relayURL, _ := url.Parse("wss://relay.ohstr.com")
	events, err := relayclient.ReadEventsFromRelay(context.Background(), relayURL, filters)
	if err != nil {
		panic(err)
	}
	for _, ev := range events {
		if err := ev.Verify(); err != nil {
			continue // bad signature, bad ID, or malformed — skip it
		}
		fmt.Println(ev.ID, ev.Content)
	}
}
Build, sign, and publish an event

Create an event, sign it with your private key, and publish it to a relay:

package main

import (
	"context"
	"fmt"
	"net/url"

	"github.com/ohstr/nmilat/nip01"
	relayclient "github.com/ohstr/nmilat/relay/client"
)

func main() {
	// privateKeyHex is your hex-encoded Nostr private key — see
	// "Encode & decode keys" below for converting to/from npub/nsec.
	ev, err := nip01.NewSignedEvent(1, "hello nostr", privateKeyHex)
	if err != nil {
		panic(err)
	}

	relayURL, _ := url.Parse("wss://relay.ohstr.com")
	conn, err := relayclient.Connect(context.Background(), relayURL)
	if err != nil {
		panic(err)
	}
	defer conn.Close()

	res, err := conn.Publish(context.Background(), ev)
	if err != nil {
		panic(err)
	}
	fmt.Println("accepted:", res.Accepted, res.Message)
}
Send a private direct message (NIP-17/59)

Build a chat message, seal and gift-wrap it so only the recipient can read it (sender identity included), and publish the wrapper like any other event:

package main

import (
	"context"
	"fmt"
	"net/url"

	"github.com/ohstr/nmilat/nip17"
	"github.com/ohstr/nmilat/nip59"
	relayclient "github.com/ohstr/nmilat/relay/client"
)

func main() {
	rumor := nip17.NewChatMessage("gm from nmilat")
	if err := rumor.Sign(senderPrivKeyHex); err != nil {
		panic(err)
	}

	// Wrap encrypts the rumor twice (seal, then gift wrap) so relays and
	// onlookers see only an anonymous kind-1059 event addressed to recipientPubKeyHex.
	giftWrap, err := nip59.Wrap(rumor, senderPrivKeyHex, recipientPubKeyHex)
	if err != nil {
		panic(err)
	}

	relayURL, _ := url.Parse("wss://relay.ohstr.com")
	conn, err := relayclient.Connect(context.Background(), relayURL)
	if err != nil {
		panic(err)
	}
	defer conn.Close()

	res, err := conn.Publish(context.Background(), giftWrap)
	if err != nil {
		panic(err)
	}
	fmt.Println("delivered:", res.Accepted, res.Message)
}
Send a zap request (NIP-57)

nip57 implements the spec-compliant kind 9734/9735 zap request/receipt/LNURL flow:

package main

import (
	"context"
	"fmt"
	"net/url"

	"github.com/ohstr/nmilat/nip57"
	relayclient "github.com/ohstr/nmilat/relay/client"
)

func main() {
	zapRequest := nip57.NewZapRequest(nip57.ZapRequestParams{
		Recipient:  recipientPubKeyHex,
		Lnurl:      recipientLnurl,
		AmountMsat: 21000,
		Relays:     []string{"wss://relay.ohstr.com"},
	})
	if err := zapRequest.Sign(senderPrivKeyHex); err != nil {
		panic(err)
	}

	relayURL, _ := url.Parse("wss://relay.ohstr.com")
	conn, err := relayclient.Connect(context.Background(), relayURL)
	if err != nil {
		panic(err)
	}
	defer conn.Close()

	res, err := conn.Publish(context.Background(), zapRequest)
	if err != nil {
		panic(err)
	}
	fmt.Println("zap request accepted:", res.Accepted, res.Message)
}
Send an AltZap request (NIP-57 extension)

AltZap is the same flow for non-Bitcoin chains — a mandatory chain tag and its own kinds (5520-5523):

package main

import (
	"context"
	"fmt"
	"net/url"

	"github.com/ohstr/nmilat/nip57"
	relayclient "github.com/ohstr/nmilat/relay/client"
)

func main() {
	zapRequest := nip57.NewAltZapRequest(nip57.AltZapRequestParams{
		Chain:       "flokicoin", // prevents cross-chain replay
		Recipient:   recipientPubKeyHex,
		Lnurl:       recipientLnurl,
		AmountMloki: 21000,
		Relays:      []string{"wss://relay.ohstr.com"},
	})
	if err := zapRequest.Sign(senderPrivKeyHex); err != nil {
		panic(err)
	}

	relayURL, _ := url.Parse("wss://relay.ohstr.com")
	conn, err := relayclient.Connect(context.Background(), relayURL)
	if err != nil {
		panic(err)
	}
	defer conn.Close()

	res, err := conn.Publish(context.Background(), zapRequest)
	if err != nil {
		panic(err)
	}
	fmt.Println("zap request accepted:", res.Accepted, res.Message)
}
Pay an invoice over Nostr Wallet Connect (NIP-47)

Parse a nostr+walletconnect:// pairing URI and construct a NWCClient — it dials the wallet's relay once and keeps the connection open for reuse across calls. PayInvoice and the other wallet operations are plain methods: no type parameter at the call site, and a wallet-side decline comes back as a *relayclient.WalletError you can errors.As for the code and message:

package main

import (
	"context"
	"fmt"

	"github.com/ohstr/nmilat/nip47"
	relayclient "github.com/ohstr/nmilat/relay/client"
)

func main() {
	// pairingURI is the nostr+walletconnect:// string the user's wallet gave
	// you; it carries the wallet's pubkey, relay(s), and your app's secret key.
	pairing, err := nip47.ParsePairingURI(pairingURI)
	if err != nil {
		panic(err)
	}

	wallet, err := relayclient.NewNWCClient(context.Background(), pairing, nip47.EncryptionNIP44V2)
	if err != nil {
		panic(err)
	}
	defer wallet.Close()

	result, err := wallet.PayInvoice(context.Background(), nip47.PayInvoiceParams{
		Invoice: "lnfcxxxx....", // lnbcxxx for bitcoin
	})
	if err != nil {
		panic(err)
	}
	fmt.Println("paid! preimage:", result.Preimage)
}
Upload a blob to a Blossom server (NIP-B7)

Build a BUD-11 Authorization token scoped to the upload verb, then hand it to nipB7/client to stream the blob to a server and get back its Blob Descriptor:

package main

import (
	"context"
	"fmt"
	"strings"
	"time"

	"github.com/ohstr/nmilat/nipB7"
	blossom "github.com/ohstr/nmilat/nipB7/client"
)

func main() {
	auth := nipB7.NewAuthorization(nipB7.AuthorizationParams{
		Verb:       nipB7.VerbUpload,
		Content:    "Upload blob",
		Expiration: time.Now().Add(5 * time.Minute),
	})
	if err := auth.Sign(privateKeyHex); err != nil {
		panic(err)
	}

	c := &blossom.Client{}
	descriptor, err := c.Upload(context.Background(), "https://blossom.example", blossom.UploadRequest{
		Body:        strings.NewReader("hello nostr"),
		Size:        11,
		ContentType: "text/plain",
		Auth:        auth,
	})
	if err != nil {
		panic(err)
	}
	fmt.Println("stored at:", descriptor.URL)
}

c.Get/c.GetFromServers download the same way (streamed, with server-list fallback), and nipB7.VerifyAuthorization is the server-side, BUD-11 analogue of NIP-98's VerifyAuthHeader.

Encode & decode entities (NIP-19)

Convert between raw hex keys/IDs and Nostr's bech32 encoding (npub/nsec/note):

import "github.com/ohstr/nmilat/nip19"

npub, err := nip19.EncodePublicKey(pubkeyHex)
if err != nil {
	panic(err)
}
fmt.Println(npub) // npub1...

decoded, err := nip19.DecodePublicKey(npub)
if err != nil {
	panic(err)
}
fmt.Println(decoded) // pubkeyHex

DecodePublicKey/DecodePrivateKey/DecodeNote are typed wrappers; the generic nip19.Decode is also available for callers that need to handle an identifier of unknown/mixed type.

The TLV-based "shareable identifiers with extra metadata" — nprofile, nevent, and naddr — carry a public key/event ID plus optional relay hints (and, for nevent/naddr, an optional author and kind):

nprofile, err := nip19.EncodeProfile(pubkeyHex, []string{"wss://relay.example.com"})
profile, err := nip19.DecodeProfile(nprofile) // *nip19.ProfilePointer{PublicKey, Relays}

nevent, err := nip19.EncodeEvent(nip19.EventPointer{
	ID:     eventIDHex,
	Relays: []string{"wss://relay.example.com"},
	Author: pubkeyHex, // optional
	Kind:   1,         // optional
})
event, err := nip19.DecodeEvent(nevent) // *nip19.EventPointer

naddr, err := nip19.EncodeAddr(nip19.EntityPointer{
	Identifier: "my-article",
	PublicKey:  pubkeyHex,
	Kind:       30023,
	Relays:     []string{"wss://relay.example.com"},
})
addr, err := nip19.DecodeAddr(naddr) // *nip19.EntityPointer

Development

Uses just for build automation:

just build   # compile-check (library, no binary)
just test    # go test ./...
just vet     # go vet ./...
just tidy    # go mod tidy
just check   # build + vet + test

License

Unlicense — public domain.

Directories

Path Synopsis
Package config holds the embedded YAML configuration for the search subsystem: profile scoring weights, NIP-05/LUD-16 verification bonuses, and search-engine/cache tuning.
Package config holds the embedded YAML configuration for the search subsystem: profile scoring weights, NIP-05/LUD-16 verification bonuses, and search-engine/cache tuning.
Package nip01 implements NIP-01: the core event, filter, and subscription types every other package in this SDK builds on — event construction, signing, verification, and NIP-01 subscription filters.
Package nip01 implements NIP-01: the core event, filter, and subscription types every other package in this SDK builds on — event construction, signing, verification, and NIP-01 subscription filters.
Package nip04 implements NIP-04: Encrypted Direct Message, the legacy (pre-NIP-44) shared-secret AES-256-CBC encryption scheme for kind-4 direct messages.
Package nip04 implements NIP-04: Encrypted Direct Message, the legacy (pre-NIP-44) shared-secret AES-256-CBC encryption scheme for kind-4 direct messages.
Package nip05 implements NIP-05: Mapping Nostr Keys to DNS-based Internet Identifiers, letting a pubkey advertise a human-readable "name@domain" identifier that resolves via a domain's /.well-known/nostr.json document.
Package nip05 implements NIP-05: Mapping Nostr Keys to DNS-based Internet Identifiers, letting a pubkey advertise a human-readable "name@domain" identifier that resolves via a domain's /.well-known/nostr.json document.
Package nip09 implements NIP-09: Event Deletion Request, the kind-5 event a user publishes to ask relays to stop serving their earlier events.
Package nip09 implements NIP-09: Event Deletion Request, the kind-5 event a user publishes to ask relays to stop serving their earlier events.
Package nip11 implements NIP-11: Relay Information Document, the application/nostr+json metadata a relay serves describing its name, supported NIPs, and connection limits.
Package nip11 implements NIP-11: Relay Information Document, the application/nostr+json metadata a relay serves describing its name, supported NIPs, and connection limits.
Package nip13 implements NIP-13: Proof of Work, letting an event embed a nonce tag whose event ID has a target number of leading zero bits.
Package nip13 implements NIP-13: Proof of Work, letting an event embed a nonce tag whose event ID has a target number of leading zero bits.
sha256
Package sha256 implements the SHA224 and SHA256 hash algorithms as defined in FIPS 180-4.
Package sha256 implements the SHA224 and SHA256 hash algorithms as defined in FIPS 180-4.
Package nip16 implements NIP-16: Event Treatment, the replaceable/ ephemeral event-kind ranges (folded into NIP-01 upstream, kept here as a distinct package for the kind-range predicates).
Package nip16 implements NIP-16: Event Treatment, the replaceable/ ephemeral event-kind ranges (folded into NIP-01 upstream, kept here as a distinct package for the kind-range predicates).
Package nip17 implements NIP-17: Private Direct Messages, unencrypted kind-14 chat rumors meant to be sealed and gift-wrapped (see nip59) before publishing.
Package nip17 implements NIP-17: Private Direct Messages, unencrypted kind-14 chat rumors meant to be sealed and gift-wrapped (see nip59) before publishing.
Package nip19 implements NIP-19: bech32-Encoded Entities, converting between raw hex keys/IDs and their human-friendly bech32 form (npub, nsec, note, nprofile, nevent, naddr).
Package nip19 implements NIP-19: bech32-Encoded Entities, converting between raw hex keys/IDs and their human-friendly bech32 form (npub, nsec, note, nprofile, nevent, naddr).
Package nip23 implements NIP-23: Long-form Content, articles published as kind:30023 parameterized-replaceable events (Markdown content plus title/summary/image metadata).
Package nip23 implements NIP-23: Long-form Content, articles published as kind:30023 parameterized-replaceable events (Markdown content plus title/summary/image metadata).
Package nip26 implements NIP-26: Delegated Event Signing, letting an issuer authorize a delegate pubkey to sign events on its behalf within caller-defined conditions (event kind, creation-time window).
Package nip26 implements NIP-26: Delegated Event Signing, letting an issuer authorize a delegate pubkey to sign events on its behalf within caller-defined conditions (event kind, creation-time window).
Package nip33 implements NIP-33: Parameterized Replaceable Events (kind 30000-39999, renamed "addressable events" and folded into NIP-01 upstream), identified by pubkey+kind+"d" tag rather than pubkey+kind alone.
Package nip33 implements NIP-33: Parameterized Replaceable Events (kind 30000-39999, renamed "addressable events" and folded into NIP-01 upstream), identified by pubkey+kind+"d" tag rather than pubkey+kind alone.
Package nip40 implements NIP-40: Expiration Timestamp, an "expiration" tag marking when relays should stop serving an event.
Package nip40 implements NIP-40: Expiration Timestamp, an "expiration" tag marking when relays should stop serving an event.
Package nip42 implements NIP-42: Relay Authentication, letting a relay challenge a client to prove control of a pubkey (via a signed kind:22242 event) before granting access to restricted reads/writes.
Package nip42 implements NIP-42: Relay Authentication, letting a relay challenge a client to prove control of a pubkey (via a signed kind:22242 event) before granting access to restricted reads/writes.
Package nip43 implements NIP-43: Relay Access Metadata and Requests -- relay membership lists, roles, and a self-service join/leave/invite flow.
Package nip43 implements NIP-43: Relay Access Metadata and Requests -- relay membership lists, roles, and a self-service join/leave/invite flow.
Package nip44 implements NIP-44: Encrypted Payloads (Versioned), the current ChaCha20+HMAC-SHA256 (encrypt-then-MAC) scheme (v2) for direct-message and other private event content, superseding the legacy AES-CBC scheme in nip04.
Package nip44 implements NIP-44: Encrypted Payloads (Versioned), the current ChaCha20+HMAC-SHA256 (encrypt-then-MAC) scheme (v2) for direct-message and other private event content, superseding the legacy AES-CBC scheme in nip04.
Package nip46 implements NIP-46: Nostr Connect (remote signing), letting a client ask a remote signer to sign events, encrypt/decrypt payloads, or hand over a public key — over an encrypted request/response event pair (kind 24133) — instead of the client holding the private key itself.
Package nip46 implements NIP-46: Nostr Connect (remote signing), letting a client ask a remote signer to sign events, encrypt/decrypt payloads, or hand over a public key — over an encrypted request/response event pair (kind 24133) — instead of the client holding the private key itself.
Package nip47 implements NIP-47: Nostr Wallet Connect (NWC), a protocol letting Nostr clients access a remote Lightning wallet service over end-to-end encrypted Nostr events, using a unique keypair per connection.
Package nip47 implements NIP-47: Nostr Wallet Connect (NWC), a protocol letting Nostr clients access a remote Lightning wallet service over end-to-end encrypted Nostr events, using a unique keypair per connection.
relayreg
Package relayreg declares NIP-47 support to a relay engine.
Package relayreg declares NIP-47 support to a relay engine.
Package nip48 implements NIP-48: Proxy tags, which let an event declare that it originated on another protocol (ActivityPub, AT Protocol, RSS, or the web) and reference its source object there.
Package nip48 implements NIP-48: Proxy tags, which let an event declare that it originated on another protocol (ActivityPub, AT Protocol, RSS, or the web) and reference its source object there.
relayreg
Package relayreg declares NIP-48 support to a relay engine.
Package relayreg declares NIP-48 support to a relay engine.
Package nip49 implements NIP-49: Private Key Encryption, the scrypt-derived, password-protected "ncryptsec" encoding for a private key.
Package nip49 implements NIP-49: Private Key Encryption, the scrypt-derived, password-protected "ncryptsec" encoding for a private key.
Package nip57 implements NIP-57 (Lightning Zaps) in two flavors:
Package nip57 implements NIP-57 (Lightning Zaps) in two flavors:
relayreg
Package relayreg declares NIP-57 (Zaps, including the AltZap extension) support to a relay engine.
Package relayreg declares NIP-57 (Zaps, including the AltZap extension) support to a relay engine.
Package nip65 implements NIP-65: Relay List Metadata, letting a user publish which relays they read from and write to (the "outbox model"), so other clients know where to find their events and send them replies.
Package nip65 implements NIP-65: Relay List Metadata, letting a user publish which relays they read from and write to (the "outbox model"), so other clients know where to find their events and send them replies.
relayreg
Package relayreg declares NIP-65 support to a relay engine.
Package relayreg declares NIP-65 support to a relay engine.
Package nip77 implements NIP-77: Negentropy Syncing, a range-based set reconciliation protocol relays and clients use to efficiently discover which events they're each missing without transferring full event lists.
Package nip77 implements NIP-77: Negentropy Syncing, a range-based set reconciliation protocol relays and clients use to efficiently discover which events they're each missing without transferring full event lists.
Package nip88 implements NIP-88: Polls, allowing clients to publish single- or multiple-choice polls (kind 1068) and votes on them (kind 1018).
Package nip88 implements NIP-88: Polls, allowing clients to publish single- or multiple-choice polls (kind 1068) and votes on them (kind 1018).
relayreg
Package relayreg declares NIP-88 support to a relay engine.
Package relayreg declares NIP-88 support to a relay engine.
Package nip90 implements NIP-90: Data Vending Machines, a marketplace flow where customers announce compute jobs and service providers compete to fulfill them.
Package nip90 implements NIP-90: Data Vending Machines, a marketplace flow where customers announce compute jobs and service providers compete to fulfill them.
relayreg
Package relayreg declares NIP-90 support to a relay engine.
Package relayreg declares NIP-90 support to a relay engine.
Package nip98 implements NIP-98: HTTP Auth, a signed kind-27235 event carried in an HTTP Authorization header to prove control of a pubkey to an HTTP server (e.g.
Package nip98 implements NIP-98: HTTP Auth, a signed kind-27235 event carried in an HTTP Authorization header to prove control of a pubkey to an HTTP server (e.g.
Package nipAA implements NIP-AA's pure, relay-independent orchestration pieces: the AUTH-event freshness check and Steps 3-4 of its relay verification algorithm (find the "auth" tag, verify it via nipOA, and evaluate only its created_at</created_at> clauses -- kind= clauses are deliberately not evaluated here, per the spec's explicit divergence from full NIP-OA verification at connection admission).
Package nipAA implements NIP-AA's pure, relay-independent orchestration pieces: the AUTH-event freshness check and Steps 3-4 of its relay verification algorithm (find the "auth" tag, verify it via nipOA, and evaluate only its created_at</created_at> clauses -- kind= clauses are deliberately not evaluated here, per the spec's explicit divergence from full NIP-OA verification at connection admission).
Package nipB0 implements NIP-B0: Web Bookmarking, editable bookmarks of web pages published as kind 39701 parameterized-replaceable events.
Package nipB0 implements NIP-B0: Web Bookmarking, editable bookmarks of web pages published as kind 39701 parameterized-replaceable events.
relayreg
Package relayreg declares NIP-B0 support to a relay engine.
Package relayreg declares NIP-B0 support to a relay engine.
Package nipB7 implements NIP-B7: Blossom media — the Nostr-facing side of the Blossom protocol (github.com/hzrd149/blossom), covering:
Package nipB7 implements NIP-B7: Blossom media — the Nostr-facing side of the Blossom protocol (github.com/hzrd149/blossom), covering:
client
Package client is an HTTP client for talking to Blossom servers (as distinct from nipB7 itself, which only builds/parses the protocol's events and types and makes no network calls).
Package client is an HTTP client for talking to Blossom servers (as distinct from nipB7 itself, which only builds/parses the protocol's events and types and makes no network calls).
relayreg
Package relayreg declares NIP-B7 support to a relay engine.
Package relayreg declares NIP-B7 support to a relay engine.
Package nipOA implements NIP-OA: Owner Attestation, an optional "auth" tag by which an owner key authorizes an agent key to publish events under the agent's own authorship.
Package nipOA implements NIP-OA: Owner Attestation, an optional "auth" tag by which an owner key authorizes an agent key to publish events under the agent's own authorship.
Package relay is an embeddable Nostr relay engine: event storage (EventStore), WebSocket session handling (SessionHandler), NIP-11 negotiation, and a plugin registration mechanism (RegisterNIP / RegisterEventValidator) that NIP packages use to declare relay support without the relay package needing to import them.
Package relay is an embeddable Nostr relay engine: event storage (EventStore), WebSocket session handling (SessionHandler), NIP-11 negotiation, and a plugin registration mechanism (RegisterNIP / RegisterEventValidator) that NIP packages use to declare relay support without the relay package needing to import them.
client
Package client is a Nostr relay WebSocket client: dial a relay (Connection), publish and subscribe, and round-trip higher-level protocols built on top of the wire format (e.g.
Package client is a Nostr relay WebSocket client: dial a relay (Connection), publish and subscribe, and round-trip higher-level protocols built on top of the wire format (e.g.
migrations
Package migrations runs versioned schema migrations against the relay package's embedded bbolt key-value store, tracking the applied version in a dedicated bucket.
Package migrations runs versioned schema migrations against the relay package's embedded bbolt key-value store, tracking the applied version in a dedicated bucket.
Package search implements profile search indexing and ranking used by the relay package to serve NIP-50 search queries: a pluggable Backend interface, a batching Service that indexes profile updates asynchronously, and a ReadOnlyService decorator for relay instances that should query but never index.
Package search implements profile search indexing and ranking used by the relay package to serve NIP-50 search queries: a pluggable Backend interface, a batching Service that indexes profile updates asynchronously, and a ReadOnlyService decorator for relay instances that should query but never index.
Package testlogger wires a zerolog.Logger into testing.T/B so that production code's own log lines (session lifecycle, verification, migrations, etc.) show up correctly attributed to the (sub)test that triggered them -- hidden on pass, surfaced automatically on failure or with `go test -v` -- instead of being silenced or dumped raw to stdout.
Package testlogger wires a zerolog.Logger into testing.T/B so that production code's own log lines (session lifecycle, verification, migrations, etc.) show up correctly attributed to the (sub)test that triggered them -- hidden on pass, surfaced automatically on failure or with `go test -v` -- instead of being silenced or dumped raw to stdout.
Package utils holds small helpers shared across this SDK's NIP and relay packages: event/tag validation, key management, NIP-05/LUD-16 URL helpers, logging, and LNURL decoding.
Package utils holds small helpers shared across this SDK's NIP and relay packages: event/tag validation, key management, NIP-05/LUD-16 URL helpers, logging, and LNURL decoding.
Package wire defines the Nostr relay wire-protocol packet types (EVENT, REQ, EOSE, OK, NOTICE, CLOSE, AUTH, and NIP-77 negentropy packets) and their JSON encoding.
Package wire defines the Nostr relay wire-protocol packet types (EVENT, REQ, EOSE, OK, NOTICE, CLOSE, AUTH, and NIP-77 negentropy packets) and their JSON encoding.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL