Documentation
¶
Overview ¶
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. This package is a pure tag-format and cryptographic-verification library: it has no dependency on relay/ and performs no relay-side behavior of its own. Per the spec, "Relays require no changes to support this NIP... Relays MUST NOT be required to verify an auth tag" -- verification is something a client, or (per NIP-AA) a relay implementing a different NIP, chooses to do with the functions here.
An event carrying a valid auth tag remains authored solely by its own pubkey; this package does not define impersonation, key derivation, or author rewriting of any kind.
Index ¶
Constants ¶
const TagName = "auth"
TagName is the tag name this package parses: ["auth", owner, conditions, sig].
Variables ¶
var ( ErrMultipleAuthTags = errors.New("nipoa: multiple auth tags") ErrWrongElementCount = errors.New("nipoa: auth tag must have exactly 4 elements") ErrInvalidOwnerPubkey = errors.New("nipoa: invalid owner pubkey") ErrInvalidSignatureHex = errors.New("nipoa: invalid signature hex") ErrSelfAttestation = errors.New("nipoa: owner pubkey must not equal event pubkey") ErrMalformedConditions = errors.New("nipoa: malformed conditions") ErrUnsupportedClause = errors.New("nipoa: unsupported condition clause") ErrSignatureVerificationFailed = errors.New("nipoa: signature verification failed") )
Failure modes, for callers that need to distinguish them (e.g. via errors.Is) rather than match on message text.
Functions ¶
func Preimage ¶
Preimage builds the exact signing preimage bytes: the domain separator, the event's pubkey, ":", and the conditions string, verbatim. eventPubkey and conditions are used byte-for-byte -- no normalization, reordering, deduplication, or canonicalization of any kind.
func VerifySignature ¶
VerifySignature checks sigHex as a BIP-340 Schnorr signature, by ownerPubkeyHex, over SHA256(Preimage(eventPubkey, conditions)). Reuses the same schnorr parsing/verification nip01.Event.Verify uses elsewhere in this SDK.
Types ¶
type Conditions ¶
Conditions is the parsed form of an auth tag's <conditions> string: zero or more clauses, each either kind=<n>, created_at<t>, or created_at>t, conjunctive -- an event (or, per NIP-AA, an AUTH event's own timestamp) must satisfy every clause.
Raw is retained verbatim because the signing preimage is built from the exact <conditions> string bytes -- per spec, implementations MUST NOT reorder, deduplicate, normalize, or canonicalize it before computing the preimage. Preimage uses Raw, never a reserialization of the parsed Kinds/CreatedAtLT/CreatedAtGT fields.
func ParseConditions ¶
func ParseConditions(raw string) (Conditions, error)
ParseConditions parses the <conditions> grammar: the empty string (no constraints), or "&"-separated clauses each of the form kind=<decimal>, created_at<<decimal>, or created_at><decimal>. Decimal values must be canonical base-10 (no leading zeros except a lone "0", no sign, no whitespace); kind values are 0-65535, created_at values are 0-4294967295. A leading, trailing, or doubled "&" produces an empty clause somewhere in the split, which is rejected uniformly by the empty-clause check below -- no special-casing needed per position.
func (Conditions) EvaluateKind ¶
func (c Conditions) EvaluateKind(kind int) bool
EvaluateKind reports whether kind satisfies every kind= clause (vacuously true if there are none). Multiple kind= clauses are conjunctive per spec -- "kind=1&kind=7" can never be satisfied by any single event, since no event has two kinds at once. That is a footgun for whoever issues such a credential, not a bug in this evaluation.
func (Conditions) EvaluateTimeClauses ¶
func (c Conditions) EvaluateTimeClauses(createdAt uint64) bool
EvaluateTimeClauses reports whether createdAt satisfies every created_at</created_at> clause (vacuously true if there are none).
type Tag ¶
type Tag struct {
OwnerPubkey string
Conditions Conditions
Sig string
}
Tag is a fully parsed and cryptographically verified auth tag.
func ParseAuthTag ¶
ParseAuthTag finds and fully verifies event's "auth" tag, if any, using eventPubkey as the event's own pubkey (the preimage's identity component). Returns (nil, nil) -- not an error -- when there is no auth tag at all: "no credential offered" is a valid, distinct outcome from "malformed credential offered", and callers (e.g. NIP-AA's Step 3, which treats the two differently) must be able to tell them apart.
Per spec: an event with two or more auth tags MUST be treated as having no valid auth tag -- but unlike the zero-tag case, this is reported as an error (ErrMultipleAuthTags), not (nil, nil), so a caller that must react differently to "no credential" vs. "malformed/ambiguous credential" (again, NIP-AA's Step 3) still can.