nip1

package
v1.0.7 Latest Latest
Warning

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

Go to latest
Published: Jan 1, 2024 License: CC0-1.0, MIT Imports: 17 Imported by: 0

Documentation

Index

Constants

View Source
const (
	Btrue     = "true"
	BtrueLen  = len(Btrue)
	Bfalse    = "false"
	BfalseLen = len(Bfalse)
)

Variables

View Source
var (
	EVENT  = string(Labels[LEvent])
	OK     = string(Labels[LOK])
	REQ    = string(Labels[LReq])
	NOTICE = string(Labels[LNotice])
	EOSE   = string(Labels[LEOSE])
	CLOSE  = string(Labels[LClose])
	CLOSED = string(Labels[LClosed])
)

With these, labels have easy short names for the strings, as well as neat consistent 1 byte enum version. Having all 3 versions also makes writing the recogniser easier.

View Source
var Labels = map[Label][]byte{
	LNil:    nil,
	LEvent:  []byte("EVENT"),
	LOK:     []byte("OK"),
	LNotice: []byte("NOTICE"),
	LEOSE:   []byte("EOSE"),
	LClose:  []byte("CLOSE"),
	LClosed: []byte("CLOSED"),
	LReq:    []byte("REQ"),
}

Labels is the nip1 envelope labels, matching the above enums.

Functions

func CopyUnmarshalFilterToFilter

func CopyUnmarshalFilterToFilter(uf *UnmarshalingFilter, f *Filter) (e error)

func FilterEqual

func FilterEqual(a, b *Filter) bool

func Hash

func Hash(in []byte) (out []byte)

func OKMessage

func OKMessage(reason OkReason, prefix string) string

OKMessage takes a string message that is to be sent in an `OK` or `CLOSED` command and prefixes it with "<prefix>: " if it doesn't already have an acceptable prefix.

Types

type CloseEnvelope

type CloseEnvelope struct {
	SubscriptionID
}

CloseEnvelope is a wrapper for a signal to cancel a subscription.

func NewCloseEnvelope

func NewCloseEnvelope(s SubscriptionID) (ce *CloseEnvelope)

func (*CloseEnvelope) Bytes

func (E *CloseEnvelope) Bytes() (s []byte)

func (*CloseEnvelope) Label

func (E *CloseEnvelope) Label() (l Label)

Label returns the label enum/type of the envelope. The relevant bytes could be retrieved using nip1.Labels[Label]

func (*CloseEnvelope) MarshalJSON

func (E *CloseEnvelope) MarshalJSON() (bytes []byte, e error)

MarshalJSON returns the JSON encoded form of the envelope.

func (*CloseEnvelope) String

func (E *CloseEnvelope) String() (s string)

func (*CloseEnvelope) ToArray

func (E *CloseEnvelope) ToArray() (a array.T)

func (*CloseEnvelope) Unmarshal

func (E *CloseEnvelope) Unmarshal(buf *text.Buffer) (e error)

Unmarshal the envelope.

type ClosedEnvelope

type ClosedEnvelope struct {
	SubscriptionID
	Reason string
}

ClosedEnvelope is a wrapper for a signal to cancel a subscription.

func NewClosedEnvelope

func NewClosedEnvelope(s SubscriptionID, reason string) (ce *ClosedEnvelope)

func (*ClosedEnvelope) Bytes

func (E *ClosedEnvelope) Bytes() (s []byte)

func (*ClosedEnvelope) Label

func (E *ClosedEnvelope) Label() (l Label)

Label returns the label enum/type of the envelope. The relevant bytes could be retrieved using nip1.Labels[Label]

func (*ClosedEnvelope) MarshalJSON

func (E *ClosedEnvelope) MarshalJSON() (bytes []byte, e error)

MarshalJSON returns the JSON encoded form of the envelope.

func (*ClosedEnvelope) String

func (E *ClosedEnvelope) String() (s string)

func (*ClosedEnvelope) ToArray

func (E *ClosedEnvelope) ToArray() (a array.T)

func (*ClosedEnvelope) Unmarshal

func (E *ClosedEnvelope) Unmarshal(buf *text.Buffer) (e error)

Unmarshal the envelope.

type EOSEEnvelope

type EOSEEnvelope struct {
	SubscriptionID
}

EOSEEnvelope is a message that indicates that all cached events have been delivered and thereafter events will be new and delivered in pubsub subscribe fashion while the socket remains open.

func (*EOSEEnvelope) Bytes

func (E *EOSEEnvelope) Bytes() (s []byte)

func (*EOSEEnvelope) Label

func (E *EOSEEnvelope) Label() (l Label)

Label returns the label enum/type of the envelope. The relevant bytes could be retrieved using nip1.Labels[Label]

func (*EOSEEnvelope) MarshalJSON

func (E *EOSEEnvelope) MarshalJSON() (bytes []byte, e error)

MarshalJSON returns the JSON encoded form of the envelope.

func (*EOSEEnvelope) String

func (E *EOSEEnvelope) String() (s string)

func (*EOSEEnvelope) ToArray

func (E *EOSEEnvelope) ToArray() (a array.T)

func (*EOSEEnvelope) Unmarshal

func (E *EOSEEnvelope) Unmarshal(buf *text.Buffer) (e error)

Unmarshal the envelope.

type Enveloper

type Enveloper interface {

	// Label returns the label enum/type of the envelope. The relevant bytes could
	// be retrieved using nip1.Labels[Label]
	Label() Label

	// MarshalJSON returns the JSON encoded form of the envelope.
	MarshalJSON() (bytes []byte, e error)

	// Unmarshal the envelope.
	Unmarshal(buf *text.Buffer) (e error)

	array.Arrayer
}

The Enveloper interface.

Note that the Unmarshal function is not UnmarshalJSON for a specific reason - it is impossible to implement a typed JSON unmarshaler in Go for an array type because it must by definition have a sentinel field which in the case of nostr is the Label. Objects have a defined collection of recognised labels and with omitempty marking the mandatory ones, acting as a "kind" of sentinel.

func ProcessEnvelope

func ProcessEnvelope(b []byte) (env Enveloper, label []byte, buf *text.Buffer,
	e error)

ProcessEnvelope scans a message and if it finds a correctly formed Envelope it unmarshals it and returns it.

If it fails, it also returns the label bytes found and the buffer, which will have the cursor at the next byte after the quote delimiter of the Label, ready for some other envelope outside of nip-01 to decode.

type Event

type Event struct {

	// ID is the SHA256 hash of the canonical encoding of the event
	ID EventID `json:"id"`

	// PubKey is the public key of the event creator in *hexadecimal* format
	PubKey string `json:"pubkey"`

	// CreatedAt is the UNIX timestamp of the event according to the event
	// creator (never trust a timestamp!)
	CreatedAt timestamp.T `json:"created_at"`

	// Kind is the nostr protocol code for the type of event. See kind.T
	Kind kind.T `json:"kind"`

	// Tags are a list of tags, which are a list of strings usually structured
	// as a 3 layer scheme indicating specific features of an event.
	Tags tags.T `json:"tags"`

	// Content is an arbitrary string that can contain anything, but usually
	// conforming to a specification relating to the Kind and the Tags.
	Content string `json:"content"`

	// Sig is the signature on the ID hash that validates as coming from the
	// Pubkey.
	Sig string `json:"sig"`
}

Event is the primary datatype of nostr. This is the form of the structure that defines its JSON string based format.

func (*Event) CheckSignature

func (ev *Event) CheckSignature() (valid bool, e error)

CheckSignature checks if the signature is valid for the id (which is a hash of the serialized event content). returns an error if the signature itself is invalid.

func (*Event) GetID

func (ev *Event) GetID() EventID

GetID serializes and returns the event ID as a hexadecimal string.

func (*Event) GetIDBytes

func (ev *Event) GetIDBytes() []byte

GetIDBytes returns the raw SHA256 hash of the canonical form of an Event.

func (*Event) MarshalJSON

func (ev *Event) MarshalJSON() (bytes []byte, e error)

func (*Event) Serialize added in v1.0.7

func (ev *Event) Serialize() []byte

func (*Event) Sign

func (ev *Event) Sign(skStr string, so ...schnorr.SignOption) (e error)

Sign signs an event with a given Secret Key encoded in hexadecimal.

func (*Event) SignWithSecKey

func (ev *Event) SignWithSecKey(sk *secp256k1.SecretKey,
	so ...schnorr.SignOption) (e error)

SignWithSecKey signs an event with a given *secp256xk1.SecretKey.

func (*Event) ToCanonical

func (ev *Event) ToCanonical() (o array.T)

ToCanonical returns a structure that provides a byte stringer that generates the canonical form used to generate the ID hash that can be signed.

func (*Event) ToObject

func (ev *Event) ToObject() (o object.T)

type EventEnvelope

type EventEnvelope struct {

	// The SubscriptionID field is optional, and may at most contain 64 characters,
	// sufficient for encoding a 256 bit hash as hex.
	SubscriptionID SubscriptionID

	// The Event is here a pointer because it should not be copied unnecessarily.
	Event *Event
}

EventEnvelope is the wrapper expected by a relay around an event.

func NewEventEnvelope

func NewEventEnvelope(si string, ev *Event) (ee *EventEnvelope, e error)

NewEventEnvelope builds an EventEnvelope from a provided SubscriptionID string and pointer to an Event, and returns either the EventEnvelope or an error if the Subscription ID is invalid or the Event is nil.

func (*EventEnvelope) Bytes

func (E *EventEnvelope) Bytes() (s []byte)

func (*EventEnvelope) Label

func (E *EventEnvelope) Label() (l Label)

Label returns the label enum/type of the envelope. The relevant bytes could be retrieved using nip1.Labels[Label]

func (*EventEnvelope) MarshalJSON

func (E *EventEnvelope) MarshalJSON() (bytes []byte, e error)

MarshalJSON returns the JSON encoded form of the envelope.

func (*EventEnvelope) String

func (E *EventEnvelope) String() (s string)

func (*EventEnvelope) ToArray

func (E *EventEnvelope) ToArray() (a array.T)

ToArray converts an EventEnvelope to a form that has a JSON formatted String and Bytes function (array.T). To get the encoded form, invoke either of these methods on the returned value.

func (*EventEnvelope) Unmarshal

func (E *EventEnvelope) Unmarshal(buf *text.Buffer) (e error)

Unmarshal the envelope.

type EventID

type EventID string

EventID is the SHA256 hash in hexadecimal of the canonical form of an event as produced by the output of Event.ToCanonical().Bytes().

func NewEventID

func NewEventID(s string) (ei EventID, e error)

NewEventID inspects a string and ensures it is a valid, 64 character long hexadecimal string, returns the string coerced to the type.

func (EventID) Bytes

func (ei EventID) Bytes() (b []byte)

func (EventID) MarshalJSON

func (ei EventID) MarshalJSON() (b []byte, e error)

func (EventID) String

func (ei EventID) String() string

func (EventID) Validate

func (ei EventID) Validate() (e error)

Validate checks the EventID string is valid hex and 64 characters long.

type Filter

type Filter struct {
	IDs     tag.T         `json:"ids,omitempty"`
	Kinds   kind.Array    `json:"kinds,omitempty"`
	Authors tag.T         `json:"authors,omitempty"`
	Tags    TagMap        `json:"-,omitempty"`
	Since   *timestamp.Tp `json:"since,omitempty"`
	Until   *timestamp.Tp `json:"until,omitempty"`
	Limit   int           `json:"limit,omitempty"`
	Search  string        `json:"search,omitempty"`
}

Filter is a query where one or all elements can be filled in.

Most of it is normal stuff but the Tags are a special case because the Go encode/json will not do what the specification requires, which is to unwrap the tag as fields.

Tags: {K1: val1, K2: val2)

must be changed to

K1: val1
K2: val2

For this reason in the original nbd-wdf/go-nostr special handling is created using the easyjson library that allows this '-' json tag to indicate to promote the key/value pairs inside to the same level of the object and not bundled inside another key.

Because we have a native key/value type designed for ordered object JSON serialization we just give it special treatment in the ToObject function.

The json tags are not here because they are worthless for unmarshalling and unnecessary for marshaling. They appear in the ToObject because all of them are optional fields.

For the simplified handling of unmarshaling this JSON abomination this struct is redefined so that the Tags fields are elaborated concretely and then the populated tags are put into the map as they are expected to be.

func (*Filter) Clone

func (f *Filter) Clone() (clone *Filter)

func (*Filter) MarshalJSON

func (f *Filter) MarshalJSON() (b []byte, e error)

func (*Filter) Matches

func (f *Filter) Matches(event *Event) bool

func (*Filter) String

func (f *Filter) String() string

func (*Filter) ToObject

func (f *Filter) ToObject() (o object.T)

func (*Filter) UnmarshalJSON

func (f *Filter) UnmarshalJSON(b []byte) (e error)

UnmarshalJSON correctly unpacks a JSON encoded Filter rolling up the Tags as they should be.

type Filters

type Filters []*Filter

func (Filters) Match

func (eff Filters) Match(event *Event) bool

func (Filters) String

func (eff Filters) String() string

func (Filters) ToArray

func (eff Filters) ToArray() (a array.T)

type Label

type Label = byte
const (
	LNil Label = iota
	LEvent
	LOK
	LNotice
	LEOSE
	LClose
	LClosed
	LReq
)

Label enums for compact identification of the label.

func GetLabel

func GetLabel(s string) (l Label)

type NoticeEnvelope

type NoticeEnvelope struct {
	Text string
}

NoticeEnvelope is a relay message intended to be shown to users in a nostr client interface.

func NewNoticeEnvelope

func NewNoticeEnvelope(text string) (E *NoticeEnvelope)

func (*NoticeEnvelope) Bytes

func (E *NoticeEnvelope) Bytes() (s []byte)

func (*NoticeEnvelope) Label

func (E *NoticeEnvelope) Label() (l Label)

Label returns the label enum/type of the envelope. The relevant bytes could be retrieved using nip1.Labels[Label]

func (*NoticeEnvelope) MarshalJSON

func (E *NoticeEnvelope) MarshalJSON() (bytes []byte, e error)

MarshalJSON returns the JSON encoded form of the envelope.

func (*NoticeEnvelope) String

func (E *NoticeEnvelope) String() (s string)

func (*NoticeEnvelope) ToArray

func (E *NoticeEnvelope) ToArray() (a array.T)

func (*NoticeEnvelope) Unmarshal

func (E *NoticeEnvelope) Unmarshal(buf *text.Buffer) (e error)

Unmarshal the envelope.

type OKEnvelope

type OKEnvelope struct {
	EventID EventID
	OK      bool
	Reason  string
}

OKEnvelope is a relay message sent in response to an EventEnvelope to indicate acceptance (OK is true), rejection and provide a human readable Reason for clients to display to users, with the first word being a machine readable reason type, as listed in the RejectReason* constants above, followed by ": " and a human readable message.

func NewOKEnvelope

func NewOKEnvelope(eventID EventID, ok bool, reason string) (o *OKEnvelope,
	e error)

func (*OKEnvelope) Bytes

func (E *OKEnvelope) Bytes() (s []byte)

func (*OKEnvelope) Label

func (E *OKEnvelope) Label() (l Label)

Label returns the label enum/type of the envelope. The relevant bytes could be retrieved using nip1.Labels[Label]

func (*OKEnvelope) MarshalJSON

func (E *OKEnvelope) MarshalJSON() (bytes []byte, e error)

MarshalJSON returns the JSON encoded form of the envelope.

func (*OKEnvelope) String

func (E *OKEnvelope) String() (s string)

func (*OKEnvelope) ToArray

func (E *OKEnvelope) ToArray() (a array.T)

ToArray converts an OKEnvelope to a form that has a JSON formatted String and Bytes function (array.T). To get the encoded form, invoke either of these methods on the returned value.

func (*OKEnvelope) Unmarshal

func (E *OKEnvelope) Unmarshal(buf *text.Buffer) (e error)

Unmarshal the envelope.

type OkReason

type OkReason string
const (
	OKPoW         OkReason = "pow"
	OKDuplicate   OkReason = "duplicate"
	OKBlocked     OkReason = "blocked"
	OKRateLimited OkReason = "rate-limited"
	OKInvalid     OkReason = "invalid"
	OKError       OkReason = "error"
)

type ReqEnvelope

type ReqEnvelope struct {
	SubscriptionID SubscriptionID
	Filters
}

ReqEnvelope is the wrapper for a query to a relay.

func (*ReqEnvelope) Bytes

func (E *ReqEnvelope) Bytes() (s []byte)

func (*ReqEnvelope) Label

func (E *ReqEnvelope) Label() (l Label)

Label returns the label enum/type of the envelope. The relevant bytes could be retrieved using nip1.Labels[Label]

func (*ReqEnvelope) MarshalJSON

func (E *ReqEnvelope) MarshalJSON() (bytes []byte, e error)

MarshalJSON returns the JSON encoded form of the envelope.

func (*ReqEnvelope) String

func (E *ReqEnvelope) String() (s string)

func (*ReqEnvelope) ToArray

func (E *ReqEnvelope) ToArray() (arr array.T)

func (*ReqEnvelope) Unmarshal

func (E *ReqEnvelope) Unmarshal(buf *text.Buffer) (e error)

Unmarshal the envelope.

type SubscriptionID

type SubscriptionID string

SubscriptionID is an arbitrary string of 1-64 characters in length generated as a request or session identifier.

func NewSubscriptionID

func NewSubscriptionID(s string) (SubscriptionID, error)

NewSubscriptionID inspects a string and converts to SubscriptionID if it is valid. Invalid means length < 0 and <= 64 (hex encoded 256 bit hash).

func (SubscriptionID) IsValid

func (si SubscriptionID) IsValid() bool

IsValid returns true if the subscription id is between 1 and 64 characters. Invalid means too long or not present.

func (SubscriptionID) MarshalJSON

func (si SubscriptionID) MarshalJSON() (b []byte, e error)

type TagMap

type TagMap map[string]tag.T

func (TagMap) Clone

func (t TagMap) Clone() (t1 TagMap)

type UnmarshalingFilter

type UnmarshalingFilter struct {
	IDs     tag.T         `json:"ids,omitempty"`
	Kinds   kind.Array    `json:"kinds,omitempty"`
	Authors tag.T         `json:"authors,omitempty"`
	Ta      tag.T         `json:"#a,omitempty"`
	Tb      tag.T         `json:"#b,omitempty"`
	Tc      tag.T         `json:"#c,omitempty"`
	Td      tag.T         `json:"#d,omitempty"`
	Te      tag.T         `json:"#e,omitempty"`
	Tf      tag.T         `json:"#f,omitempty"`
	Tg      tag.T         `json:"#g,omitempty"`
	Th      tag.T         `json:"#h,omitempty"`
	Ti      tag.T         `json:"#i,omitempty"`
	Tj      tag.T         `json:"#j,omitempty"`
	Tk      tag.T         `json:"#k,omitempty"`
	Tl      tag.T         `json:"#l,omitempty"`
	Tm      tag.T         `json:"#m,omitempty"`
	Tn      tag.T         `json:"#n,omitempty"`
	To      tag.T         `json:"#o,omitempty"`
	Tp      tag.T         `json:"#p,omitempty"`
	Tq      tag.T         `json:"#q,omitempty"`
	Tr      tag.T         `json:"#r,omitempty"`
	Ts      tag.T         `json:"#s,omitempty"`
	Tt      tag.T         `json:"#t,omitempty"`
	Tu      tag.T         `json:"#u,omitempty"`
	Tv      tag.T         `json:"#v,omitempty"`
	Tw      tag.T         `json:"#w,omitempty"`
	Tx      tag.T         `json:"#x,omitempty"`
	Ty      tag.T         `json:"#y,omitempty"`
	TA      tag.T         `json:"#A,omitempty"`
	TB      tag.T         `json:"#B,omitempty"`
	TC      tag.T         `json:"#C,omitempty"`
	TD      tag.T         `json:"#D,omitempty"`
	TE      tag.T         `json:"#E,omitempty"`
	TF      tag.T         `json:"#F,omitempty"`
	TG      tag.T         `json:"#G,omitempty"`
	TH      tag.T         `json:"#H,omitempty"`
	TI      tag.T         `json:"#I,omitempty"`
	TJ      tag.T         `json:"#J,omitempty"`
	TK      tag.T         `json:"#K,omitempty"`
	TL      tag.T         `json:"#L,omitempty"`
	TM      tag.T         `json:"#M,omitempty"`
	TN      tag.T         `json:"#N,omitempty"`
	TO      tag.T         `json:"#O,omitempty"`
	TP      tag.T         `json:"#P,omitempty"`
	TQ      tag.T         `json:"#Q,omitempty"`
	TR      tag.T         `json:"#R,omitempty"`
	TS      tag.T         `json:"#S,omitempty"`
	TT      tag.T         `json:"#T,omitempty"`
	TU      tag.T         `json:"#U,omitempty"`
	TV      tag.T         `json:"#V,omitempty"`
	TW      tag.T         `json:"#W,omitempty"`
	TX      tag.T         `json:"#X,omitempty"`
	TY      tag.T         `json:"#Y,omitempty"`
	Since   *timestamp.Tp `json:"since,omitempty"`
	Until   *timestamp.Tp `json:"until,omitempty"`
	Limit   int           `json:"limit,omitempty"`
	Search  string        `json:"search,omitempty"`
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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