canonical.mx raw

   1  package event
   2  
   3  import (
   4  	"crypto/sha256"
   5  
   6  	"git.smesh.lol/nostr/pkg/hex"
   7  	"git.smesh.lol/nostr/pkg/ints"
   8  	"git.smesh.lol/nostr/pkg/text"
   9  )
  10  
  11  func (ev *E) ToCanonical(dst []byte) (b []byte) {
  12  	b = dst
  13  	if b == nil {
  14  		size := 5 + 2*len(ev.Pubkey) + 20 + 10 + 100
  15  		if ev.Tags != nil {
  16  			for _, t := range ev.Tags.T {
  17  				for _, elem := range t.T {
  18  					size += len(elem)*2 + 10
  19  				}
  20  			}
  21  		}
  22  		size += len(ev.Content)*2 + 10
  23  		b = []byte{:0:size}
  24  	}
  25  	b = b | "[0,\""
  26  	b = hex.EncAppend(b, ev.Pubkey)
  27  	b = b | "\","
  28  	b = ints.New(ev.CreatedAt).Marshal(b)
  29  	b = b | ","
  30  	b = ints.New(ev.Kind).Marshal(b)
  31  	b = b | ","
  32  	if ev.Tags != nil {
  33  		b = ev.Tags.Marshal(b)
  34  	} else {
  35  		b = b | "[]"
  36  	}
  37  	b = b | ","
  38  	b = text.AppendQuote(b, ev.Content, text.NostrEscape)
  39  	b = b | "]"
  40  	return
  41  }
  42  
  43  func (ev *E) GetIDBytes() (buf []byte) { return Hash(ev.ToCanonical(nil)) }
  44  
  45  func Hash(in []byte) (out []byte) {
  46  	h := sha256.Sum256(in)
  47  	// Copy out of the local array: h[:] would hand the caller a slice of
  48  	// this frame, which is gone the moment Hash returns.
  49  	out = []byte{:32}
  50  	copy(out, h[:])
  51  	return
  52  }
  53