Documentation ¶
Index ¶
- Constants
- Variables
- func FilterEqual(a Filter, b Filter) bool
- func GeneratePrivateKey() string
- func GetPublicKey(sk string) (string, error)
- func IsValidPublicKeyHex(pk string) bool
- func IsValidRelayURL(u string) bool
- func NormalizeOKMessage(reason string, prefix string) string
- func NormalizeURL(u string) string
- type AuthEnvelope
- type CloseEnvelope
- type ClosedEnvelope
- type Connection
- type CountEnvelope
- type EOSEEnvelope
- type EntityPointer
- type Envelope
- type Event
- func (evt Event) CheckSignature() (bool, error)
- func (evt Event) GetExtra(key string) any
- func (evt Event) GetExtraBoolean(key string) bool
- func (evt Event) GetExtraNumber(key string) float64
- func (evt Event) GetExtraString(key string) string
- func (evt *Event) GetID() string
- func (v Event) MarshalEasyJSON(w *jwriter.Writer)
- func (v Event) MarshalJSON() ([]byte, error)
- func (evt *Event) RemoveExtra(key string)
- func (evt *Event) Serialize() []byte
- func (evt *Event) SetExtra(key string, value any)
- func (evt *Event) Sign(privateKey string, signOpts ...schnorr.SignOption) error
- func (evt Event) String() string
- func (v *Event) UnmarshalEasyJSON(l *jlexer.Lexer)
- func (v *Event) UnmarshalJSON(data []byte) error
- type EventEnvelope
- type EventMessage
- type EventPointer
- type Filter
- func (ef Filter) Clone() Filter
- func (v Filter) MarshalEasyJSON(w *jwriter.Writer)
- func (v Filter) MarshalJSON() ([]byte, error)
- func (ef Filter) Matches(event *Event) bool
- func (ef Filter) String() string
- func (v *Filter) UnmarshalEasyJSON(l *jlexer.Lexer)
- func (v *Filter) UnmarshalJSON(data []byte) error
- type Filters
- type IncomingEvent
- type NoticeEnvelope
- type OKEnvelope
- type PoolOption
- type ProfilePointer
- type Relay
- func (r *Relay) Auth(ctx context.Context, sign func(event *Event) error) error
- func (r *Relay) Close() error
- func (r *Relay) Connect(ctx context.Context) error
- func (r *Relay) Context() context.Context
- func (r *Relay) Count(ctx context.Context, filters Filters, opts ...SubscriptionOption) (int64, error)
- func (r *Relay) IsConnected() bool
- func (r *Relay) PrepareSubscription(ctx context.Context, filters Filters, opts ...SubscriptionOption) *Subscription
- func (r *Relay) Publish(ctx context.Context, event Event) error
- func (r *Relay) QuerySync(ctx context.Context, filter Filter, opts ...SubscriptionOption) ([]*Event, error)
- func (r *Relay) String() string
- func (r *Relay) Subscribe(ctx context.Context, filters Filters, opts ...SubscriptionOption) (*Subscription, error)
- func (r *Relay) Write(msg []byte) <-chan error
- type RelayOption
- type ReqEnvelope
- type SimplePool
- func (pool *SimplePool) EnsureRelay(url string) (*Relay, error)
- func (pool *SimplePool) QuerySingle(ctx context.Context, urls []string, filter Filter) *IncomingEvent
- func (pool *SimplePool) SubMany(ctx context.Context, urls []string, filters Filters) chan IncomingEvent
- func (pool *SimplePool) SubManyEose(ctx context.Context, urls []string, filters Filters) chan IncomingEvent
- func (pool *SimplePool) SubManyEoseNonUnique(ctx context.Context, urls []string, filters Filters) chan IncomingEvent
- func (pool *SimplePool) SubManyNonUnique(ctx context.Context, urls []string, filters Filters) chan IncomingEvent
- type Status
- type Subscription
- type SubscriptionOption
- type Tag
- type TagMap
- type Tags
- func (tags Tags) AppendUnique(tag Tag) Tags
- func (tags Tags) ContainsAny(tagName string, values []string) bool
- func (tags Tags) FilterOut(tagPrefix []string) Tags
- func (tags Tags) GetAll(tagPrefix []string) Tags
- func (tags Tags) GetD() string
- func (tags Tags) GetFirst(tagPrefix []string) *Tag
- func (tags Tags) GetLast(tagPrefix []string) *Tag
- func (t *Tags) Scan(src any) error
- type Timestamp
- type WithAuthHandler
- type WithLabel
- type WithNoticeHandler
Examples ¶
Constants ¶
const ( KindProfileMetadata int = 0 KindTextNote int = 1 KindRecommendServer int = 2 KindContactList int = 3 KindEncryptedDirectMessage int = 4 KindDeletion int = 5 KindRepost int = 6 KindReaction int = 7 KindSimpleGroupChatMessage int = 9 KindSimpleGroupThread int = 11 KindSimpleGroupReply int = 12 KindChannelCreation int = 40 KindChannelMetadata int = 41 KindChannelMessage int = 42 KindChannelHideMessage int = 43 KindChannelMuteUser int = 44 KindFileMetadata int = 1063 KindSimpleGroupAddUser int = 9000 KindSimpleGroupRemoveUser int = 9001 KindSimpleGroupEditMetadata int = 9002 KindSimpleGroupAddPermission int = 9003 KindSimpleGroupRemovePermission int = 9004 KindSimpleGroupDeleteEvent int = 9005 KindSimpleGroupEditGroupStatus int = 9006 KindZapRequest int = 9734 KindZap int = 9735 KindMuteList int = 10000 KindPinList int = 10001 KindRelayListMetadata int = 10002 KindNWCWalletInfo int = 13194 KindClientAuthentication int = 22242 KindNWCWalletRequest int = 23194 KindNWCWalletResponse int = 23195 KindNostrConnect int = 24133 KindCategorizedPeopleList int = 30000 KindCategorizedBookmarksList int = 30001 KindProfileBadges int = 30008 KindBadgeDefinition int = 30009 KindStallDefinition int = 30017 KindProductDefinition int = 30018 KindArticle int = 30023 KindApplicationSpecificData int = 30078 KindSimpleGroupMetadata int = 39000 KindSimpleGroupAdmins int = 39001 KindSimpleGroupMembers int = 39002 )
const MAX_LOCKS = 50
Variables ¶
Functions ¶
func FilterEqual ¶
func GeneratePrivateKey ¶
func GeneratePrivateKey() string
func GetPublicKey ¶
func IsValidPublicKeyHex ¶ added in v0.14.0
func IsValidRelayURL ¶ added in v0.19.3
func NormalizeOKMessage ¶ added in v0.26.0
NormalizeOKMessage 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.
func NormalizeURL ¶
NormalizeURL normalizes the url and replaces http://, https:// schemes with ws://, wss:// and normalizes the path.
Example ¶
fmt.Println(NormalizeURL("")) fmt.Println(NormalizeURL("wss://x.com/y")) fmt.Println(NormalizeURL("wss://x.com/y/")) fmt.Println(NormalizeURL("http://x.com/y")) fmt.Println(NormalizeURL(NormalizeURL("http://x.com/y"))) fmt.Println(NormalizeURL("wss://x.com")) fmt.Println(NormalizeURL("wss://x.com/")) fmt.Println(NormalizeURL(NormalizeURL(NormalizeURL("wss://x.com/")))) fmt.Println(NormalizeURL("x.com")) fmt.Println(NormalizeURL("x.com/")) fmt.Println(NormalizeURL("x.com////")) fmt.Println(NormalizeURL("x.com/?x=23"))
Output: wss://x.com/y wss://x.com/y ws://x.com/y ws://x.com/y wss://x.com wss://x.com wss://x.com wss://x.com wss://x.com wss://x.com wss://x.com?x=23
Types ¶
type AuthEnvelope ¶ added in v0.18.1
func (AuthEnvelope) Label ¶ added in v0.18.1
func (_ AuthEnvelope) Label() string
func (AuthEnvelope) MarshalJSON ¶ added in v0.18.1
func (v AuthEnvelope) MarshalJSON() ([]byte, error)
func (AuthEnvelope) String ¶ added in v0.27.0
func (a AuthEnvelope) String() string
func (*AuthEnvelope) UnmarshalJSON ¶ added in v0.18.1
func (v *AuthEnvelope) UnmarshalJSON(data []byte) error
type CloseEnvelope ¶ added in v0.18.1
type CloseEnvelope string
func (CloseEnvelope) Label ¶ added in v0.18.1
func (_ CloseEnvelope) Label() string
func (CloseEnvelope) MarshalJSON ¶ added in v0.18.1
func (v CloseEnvelope) MarshalJSON() ([]byte, error)
func (CloseEnvelope) String ¶ added in v0.27.0
func (c CloseEnvelope) String() string
func (*CloseEnvelope) UnmarshalJSON ¶ added in v0.18.1
func (v *CloseEnvelope) UnmarshalJSON(data []byte) error
type ClosedEnvelope ¶ added in v0.26.0
func (ClosedEnvelope) Label ¶ added in v0.26.0
func (_ ClosedEnvelope) Label() string
func (ClosedEnvelope) MarshalJSON ¶ added in v0.26.0
func (v ClosedEnvelope) MarshalJSON() ([]byte, error)
func (ClosedEnvelope) String ¶ added in v0.27.0
func (c ClosedEnvelope) String() string
func (*ClosedEnvelope) UnmarshalJSON ¶ added in v0.26.0
func (v *ClosedEnvelope) UnmarshalJSON(data []byte) error
type Connection ¶
type Connection struct {
// contains filtered or unexported fields
}
func NewConnection ¶
func (*Connection) Close ¶
func (c *Connection) Close() error
func (*Connection) ReadMessage ¶ added in v0.18.0
func (*Connection) WriteMessage ¶
func (c *Connection) WriteMessage(data []byte) error
type CountEnvelope ¶ added in v0.19.4
func (CountEnvelope) Label ¶ added in v0.19.4
func (_ CountEnvelope) Label() string
func (CountEnvelope) MarshalJSON ¶ added in v0.19.4
func (v CountEnvelope) MarshalJSON() ([]byte, error)
func (CountEnvelope) String ¶ added in v0.27.0
func (c CountEnvelope) String() string
func (*CountEnvelope) UnmarshalJSON ¶ added in v0.19.4
func (v *CountEnvelope) UnmarshalJSON(data []byte) error
type EOSEEnvelope ¶ added in v0.18.1
type EOSEEnvelope string
func (EOSEEnvelope) Label ¶ added in v0.18.1
func (_ EOSEEnvelope) Label() string
func (EOSEEnvelope) MarshalJSON ¶ added in v0.18.1
func (v EOSEEnvelope) MarshalJSON() ([]byte, error)
func (EOSEEnvelope) String ¶ added in v0.27.0
func (e EOSEEnvelope) String() string
func (*EOSEEnvelope) UnmarshalJSON ¶ added in v0.18.1
func (v *EOSEEnvelope) UnmarshalJSON(data []byte) error
type EntityPointer ¶ added in v0.14.0
type Envelope ¶ added in v0.18.1
type Envelope interface { Label() string UnmarshalJSON([]byte) error MarshalJSON() ([]byte, error) String() string }
func ParseMessage ¶ added in v0.18.1
type Event ¶
type Event struct { ID string `json:"id"` PubKey string `json:"pubkey"` CreatedAt Timestamp `json:"created_at"` Kind int `json:"kind"` Tags Tags `json:"tags"` Content string `json:"content"` Sig string `json:"sig"` // contains filtered or unexported fields }
func (Event) CheckSignature ¶
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) GetExtra ¶ added in v0.8.2
GetExtra tries to get a value under the given key that may be present in the event object but is hidden in the basic type since it is out of the spec.
func (Event) GetExtraBoolean ¶ added in v0.8.2
GetExtraBoolean is like Event.GetExtra, but only works if the value is a boolean, otherwise returns the zero-value.
func (Event) GetExtraNumber ¶ added in v0.8.2
GetExtraNumber is like Event.GetExtra, but only works if the value is a float64, otherwise returns the zero-value.
func (Event) GetExtraString ¶ added in v0.8.2
GetExtraString is like Event.GetExtra, but only works if the value is a string, otherwise returns the zero-value.
func (Event) MarshalEasyJSON ¶ added in v0.17.0
MarshalEasyJSON supports easyjson.Marshaler interface
func (Event) MarshalJSON ¶
MarshalJSON supports json.Marshaler interface
func (*Event) RemoveExtra ¶ added in v0.24.0
RemoveExtra removes an out-of-the-spec value under the given key from the event object.
func (*Event) Serialize ¶
Serialize outputs a byte array that can be hashed/signed to identify/authenticate. JSON encoding as defined in RFC4627.
func (*Event) SetExtra ¶ added in v0.8.2
SetExtra sets an out-of-the-spec value under the given key into the event object.
func (*Event) Sign ¶
func (evt *Event) Sign(privateKey string, signOpts ...schnorr.SignOption) error
Sign signs an event with a given privateKey.
func (Event) String ¶ added in v0.16.3
Event Stringer interface, just returns the raw JSON as a string.
func (*Event) UnmarshalEasyJSON ¶ added in v0.17.0
UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (*Event) UnmarshalJSON ¶
UnmarshalJSON supports json.Unmarshaler interface
type EventEnvelope ¶ added in v0.18.1
func (EventEnvelope) Label ¶ added in v0.18.1
func (_ EventEnvelope) Label() string
func (EventEnvelope) MarshalJSON ¶ added in v0.18.1
func (v EventEnvelope) MarshalJSON() ([]byte, error)
func (*EventEnvelope) UnmarshalJSON ¶ added in v0.18.1
func (v *EventEnvelope) UnmarshalJSON(data []byte) error
type EventMessage ¶
type EventPointer ¶ added in v0.13.0
type Filter ¶
type Filter struct { IDs []string `json:"ids,omitempty"` Kinds []int `json:"kinds,omitempty"` Authors []string `json:"authors,omitempty"` Tags TagMap `json:"-,omitempty"` Since *Timestamp `json:"since,omitempty"` Until *Timestamp `json:"until,omitempty"` Limit int `json:"limit,omitempty"` Search string `json:"search,omitempty"` }
func (Filter) MarshalEasyJSON ¶ added in v0.17.0
MarshalEasyJSON supports easyjson.Marshaler interface
func (Filter) MarshalJSON ¶
MarshalJSON supports json.Marshaler interface
func (*Filter) UnmarshalEasyJSON ¶ added in v0.17.0
UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (*Filter) UnmarshalJSON ¶
UnmarshalJSON supports json.Unmarshaler interface
type IncomingEvent ¶ added in v0.23.0
type NoticeEnvelope ¶ added in v0.18.1
type NoticeEnvelope string
func (NoticeEnvelope) Label ¶ added in v0.18.1
func (_ NoticeEnvelope) Label() string
func (NoticeEnvelope) MarshalJSON ¶ added in v0.18.1
func (v NoticeEnvelope) MarshalJSON() ([]byte, error)
func (NoticeEnvelope) String ¶ added in v0.27.0
func (n NoticeEnvelope) String() string
func (*NoticeEnvelope) UnmarshalJSON ¶ added in v0.18.1
func (v *NoticeEnvelope) UnmarshalJSON(data []byte) error
type OKEnvelope ¶ added in v0.18.1
func (OKEnvelope) Label ¶ added in v0.18.1
func (_ OKEnvelope) Label() string
func (OKEnvelope) MarshalJSON ¶ added in v0.18.1
func (v OKEnvelope) MarshalJSON() ([]byte, error)
func (OKEnvelope) String ¶ added in v0.27.0
func (o OKEnvelope) String() string
func (*OKEnvelope) UnmarshalJSON ¶ added in v0.18.1
func (v *OKEnvelope) UnmarshalJSON(data []byte) error
type PoolOption ¶ added in v0.27.0
type PoolOption interface { IsPoolOption() Apply(*SimplePool) }
type ProfilePointer ¶ added in v0.13.0
type Relay ¶
type Relay struct { URL string RequestHeader http.Header // e.g. for origin header Connection *Connection Subscriptions *xsync.MapOf[string, *Subscription] ConnectionError error // custom things that aren't often used // AssumeValid bool // this will skip verifying signatures for events received from this relay // contains filtered or unexported fields }
func NewRelay ¶
func NewRelay(ctx context.Context, url string, opts ...RelayOption) *Relay
NewRelay returns a new relay. The relay connection will be closed when the context is canceled.
func RelayConnect ¶ added in v0.8.1
RelayConnect returns a relay object connected to url. Once successfully connected, cancelling ctx has no effect. To close the connection, call r.Close().
func (*Relay) Auth ¶ added in v0.12.0
Auth sends an "AUTH" command client->relay as in NIP-42 and waits for an OK response.
func (*Relay) Connect ¶
Connect tries to establish a websocket connection to r.URL. If the context expires before the connection is complete, an error is returned. Once successfully connected, context expiration has no effect: call r.Close to close the connection.
The underlying relay connection will use a background context. If you want to pass a custom context to the underlying relay connection, use NewRelay() and then Relay.Connect().
func (*Relay) Context ¶ added in v0.18.1
Context retrieves the context that is associated with this relay connection.
func (*Relay) IsConnected ¶ added in v0.19.0
IsConnected returns true if the connection to this relay seems to be active.
func (*Relay) PrepareSubscription ¶ added in v0.8.2
func (r *Relay) PrepareSubscription(ctx context.Context, filters Filters, opts ...SubscriptionOption) *Subscription
PrepareSubscription creates a subscription, but doesn't fire it.
Remember to cancel subscriptions, either by calling `.Unsub()` on them or ensuring their `context.Context` will be canceled at some point. Failure to do that will result in a huge number of halted goroutines being created.
func (*Relay) Publish ¶
Publish sends an "EVENT" command to the relay r as in NIP-01 and waits for an OK response.
func (*Relay) Subscribe ¶
func (r *Relay) Subscribe(ctx context.Context, filters Filters, opts ...SubscriptionOption) (*Subscription, error)
Subscribe sends a "REQ" command to the relay r as in NIP-01. Events are returned through the channel sub.Events. The subscription is closed when context ctx is cancelled ("CLOSE" in NIP-01).
Remember to cancel subscriptions, either by calling `.Unsub()` on them or ensuring their `context.Context` will be canceled at some point. Failure to do that will result in a huge number of halted goroutines being created.
type RelayOption ¶ added in v0.19.0
type RelayOption interface {
IsRelayOption()
}
When instantiating relay connections, some options may be passed. RelayOption is the type of the argument passed for that.
type ReqEnvelope ¶ added in v0.18.1
func (ReqEnvelope) Label ¶ added in v0.18.1
func (_ ReqEnvelope) Label() string
func (ReqEnvelope) MarshalJSON ¶ added in v0.18.1
func (v ReqEnvelope) MarshalJSON() ([]byte, error)
func (*ReqEnvelope) UnmarshalJSON ¶ added in v0.18.1
func (v *ReqEnvelope) UnmarshalJSON(data []byte) error
type SimplePool ¶ added in v0.18.0
type SimplePool struct { Relays *xsync.MapOf[string, *Relay] Context context.Context // contains filtered or unexported fields }
func NewSimplePool ¶ added in v0.18.0
func NewSimplePool(ctx context.Context, opts ...PoolOption) *SimplePool
func (*SimplePool) EnsureRelay ¶ added in v0.18.0
func (pool *SimplePool) EnsureRelay(url string) (*Relay, error)
func (*SimplePool) QuerySingle ¶ added in v0.20.0
func (pool *SimplePool) QuerySingle(ctx context.Context, urls []string, filter Filter) *IncomingEvent
QuerySingle returns the first event returned by the first relay, cancels everything else.
func (*SimplePool) SubMany ¶ added in v0.18.0
func (pool *SimplePool) SubMany(ctx context.Context, urls []string, filters Filters) chan IncomingEvent
SubMany opens a subscription with the given filters to multiple relays the subscriptions only end when the context is canceled
func (*SimplePool) SubManyEose ¶ added in v0.18.0
func (pool *SimplePool) SubManyEose(ctx context.Context, urls []string, filters Filters) chan IncomingEvent
SubManyEose is like SubMany, but it stops subscriptions and closes the channel when gets a EOSE
func (*SimplePool) SubManyEoseNonUnique ¶ added in v0.24.0
func (pool *SimplePool) SubManyEoseNonUnique(ctx context.Context, urls []string, filters Filters) chan IncomingEvent
SubManyEoseNonUnique is like SubManyEose, but returns duplicate events if they come from different relays
func (*SimplePool) SubManyNonUnique ¶ added in v0.24.0
func (pool *SimplePool) SubManyNonUnique(ctx context.Context, urls []string, filters Filters) chan IncomingEvent
SubManyNonUnique is like SubMany, but returns duplicate events if they come from different relays
type Subscription ¶
type Subscription struct { Relay *Relay Filters Filters // the Events channel emits all EVENTs that come in a Subscription // will be closed when the subscription ends Events chan *Event // the EndOfStoredEvents channel gets closed when an EOSE comes for that subscription EndOfStoredEvents chan struct{} // the ClosedReason channel emits the reason when a CLOSED message is received ClosedReason chan string // Context will be .Done() when the subscription ends Context context.Context // contains filtered or unexported fields }
func (*Subscription) Close ¶ added in v0.19.0
func (sub *Subscription) Close()
Close just sends a CLOSE message. You probably want Unsub() instead.
func (*Subscription) Fire ¶ added in v0.8.2
func (sub *Subscription) Fire() error
Fire sends the "REQ" command to the relay.
func (*Subscription) GetID ¶ added in v0.14.0
func (sub *Subscription) GetID() string
GetID return the Nostr subscription ID as given to the Relay it is a concatenation of the label and a serial number.
func (*Subscription) Sub ¶
func (sub *Subscription) Sub(_ context.Context, filters Filters)
Sub sets sub.Filters and then calls sub.Fire(ctx). The subscription will be closed if the context expires.
func (*Subscription) Unsub ¶
func (sub *Subscription) Unsub()
Unsub closes the subscription, sending "CLOSE" to relay as in NIP-01. Unsub() also closes the channel sub.Events and makes a new one.
type SubscriptionOption ¶ added in v0.19.0
type SubscriptionOption interface {
IsSubscriptionOption()
}
When instantiating relay connections, some options may be passed. SubscriptionOption is the type of the argument passed for that. Some examples are WithLabel.
type Tag ¶
type Tag []string
func (Tag) StartsWith ¶
StartsWith checks if a tag contains a prefix. for example,
["p", "abcdef...", "wss://relay.com"]
would match against
["p", "abcdef..."]
or even
["p", "abcdef...", "wss://"]
type Tags ¶
type Tags []Tag
func (Tags) AppendUnique ¶
AppendUnique appends a tag if it doesn't exist yet, otherwise does nothing. the uniqueness comparison is done based only on the first 2 elements of the tag.
func (Tags) FilterOut ¶
FilterOut removes all tags that match the prefix, see Tag.StartsWith
func (Tags) GetAll ¶
GetAll gets all the tags that match the prefix, see Tag.StartsWith
func (Tags) GetD ¶ added in v0.27.4
GetD gets the first "d" tag (for parameterized replaceable events) value or ""
func (Tags) GetFirst ¶
GetFirst gets the first tag in tags that matches the prefix, see Tag.StartsWith
func (Tags) GetLast ¶
GetLast gets the last tag in tags that matches the prefix, see Tag.StartsWith
type WithAuthHandler ¶ added in v0.19.0
WithAuthHandler must be a function that signs the auth event when called. it will be called whenever any relay in the pool returns a `CLOSED` message with the "auth-required:" prefix, only once for each relay
func (WithAuthHandler) Apply ¶ added in v0.27.0
func (h WithAuthHandler) Apply(pool *SimplePool)
func (WithAuthHandler) IsPoolOption ¶ added in v0.27.0
func (_ WithAuthHandler) IsPoolOption()
type WithLabel ¶ added in v0.19.0
type WithLabel string
WithLabel puts a label on the subscription (it is prepended to the automatic id) that is sent to relays.
func (WithLabel) IsSubscriptionOption ¶ added in v0.19.0
func (_ WithLabel) IsSubscriptionOption()
type WithNoticeHandler ¶ added in v0.19.0
type WithNoticeHandler func(notice string)
WithNoticeHandler just takes notices and is expected to do something with them. when not given, defaults to logging the notices.
func (WithNoticeHandler) IsRelayOption ¶ added in v0.19.0
func (_ WithNoticeHandler) IsRelayOption()
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
Package nip13 implements NIP-13 See https://github.com/nostr-protocol/nips/blob/master/13.md for details.
|
Package nip13 implements NIP-13 See https://github.com/nostr-protocol/nips/blob/master/13.md for details. |