event.mx raw

   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