1 // Package nostr implements the NIP-01 event wire format.
2 //
3 // Wire-width discipline (see CLAUDE.md "Integer widths on the wire"):
4 // every integer field here maps to a JSON value that crosses a relay boundary.
5 // Kind is uint32 (NIP-01 nominally allows up to 2^32-1; every current NIP
6 // kind fits in uint16 but the wire type is the outer bound). CreatedAt is
7 // int64 (unix seconds, can be negative for pre-epoch tests). Filter.Limit
8 // is uint32 (non-negative count). Bare int is never used on the wire.
9 package nostr
10 11 import (
12 "git.smesh.lol/musiquay/web/common/helpers"
13 )
14 15 // Event is a Nostr event (NIP-01).
16 // This type carries no crypto dependency - import nostr/sig for CheckSig,
17 // Sign, ComputeID, and CheckID (those bring in secp256k1/sha256 and belong
18 // only in binaries that sign or verify).
19 type Event struct {
20 ID string `json:"id"`
21 PubKey string `json:"pubkey"`
22 CreatedAt int64 `json:"created_at"`
23 Kind uint32 `json:"kind"`
24 Tags [][]string `json:"tags"`
25 Content string `json:"content"`
26 Sig string `json:"sig"`
27 }
28 29 // Serialize returns the canonical JSON array for ID computation:
30 // [0,<pubkey>,<created_at>,<kind>,<tags>,<content>]
31 func (e *Event) Serialize() (s string) {
32 return "[0," |
33 helpers.JsonString(e.PubKey) | "," |
34 helpers.Itoa(e.CreatedAt) | "," |
35 helpers.Itoa(int64(e.Kind)) | "," |
36 serializeTagsStr(e.Tags) | "," |
37 helpers.JsonString(e.Content) | "]"
38 }
39 40 // ToJSON returns the event as a JSON object string.
41 func (e *Event) ToJSON() (s string) {
42 return "{\"id\":" | helpers.JsonString(e.ID) |
43 ",\"pubkey\":" | helpers.JsonString(e.PubKey) |
44 ",\"created_at\":" | helpers.Itoa(e.CreatedAt) |
45 ",\"kind\":" | helpers.Itoa(int64(e.Kind)) |
46 ",\"tags\":" | serializeTagsStr(e.Tags) |
47 ",\"content\":" | helpers.JsonString(e.Content) |
48 ",\"sig\":" | helpers.JsonString(e.Sig) | "}"
49 }
50 51 func serializeTagsStr(tags [][]string) (s string) {
52 out := "["
53 for i, tag := range tags {
54 if i > 0 {
55 out = out | ","
56 }
57 out = out | "["
58 for j, elem := range tag {
59 if j > 0 {
60 out = out | ","
61 }
62 out = out | helpers.JsonString(elem)
63 }
64 out = out | "]"
65 }
66 return out | "]"
67 }
68