Documentation
¶
Overview ¶
Package ws provides both relay and client websocket implementations, including a pool for fanning out to multiple relays and managing subscriptions.
Package ws implements nostr websockets with their authentication state.
Index ¶
- Constants
- func WithPenaltyBox() withPenaltyBoxOpt
- func WithRelayOptions(ropts ...RelayOption) withRelayOptionsOpt
- type Client
- func (r *Client) Auth(ctx context.Context, sign signer.I) (err error)
- func (r *Client) Close() error
- func (r *Client) Connect(ctx context.Context) error
- func (r *Client) ConnectWithTLS(ctx context.Context, tlsConfig *tls.Config) error
- func (r *Client) Context() context.Context
- func (r *Client) IsConnected() bool
- func (r *Client) PrepareSubscription(ctx context.Context, ff *filters.T, opts ...SubscriptionOption) (sub *Subscription)
- func (r *Client) Publish(ctx context.Context, event *event.E) error
- func (r *Client) QueryEvents(ctx context.Context, f *filter.F) (evc event.C, err error)
- func (r *Client) QuerySync(ctx context.Context, ff *filter.F) ([]*event.E, error)
- func (r *Client) String() string
- func (r *Client) Subscribe(ctx context.Context, ff *filters.T, opts ...SubscriptionOption) (*Subscription, error)
- func (r *Client) Write(msg []byte) <-chan error
- type Connection
- type DirectedFilter
- type Listener
- func (ws *Listener) AuthRequested() (read bool)
- func (ws *Listener) AuthedPubkey() []byte
- func (ws *Listener) Challenge() []byte
- func (ws *Listener) Close() (err error)
- func (ws *Listener) GetPendingEvent() (ev *event.E)
- func (ws *Listener) IsAuthed() bool
- func (ws *Listener) RealRemote() string
- func (ws *Listener) Req() *http.Request
- func (ws *Listener) RequestAuth()
- func (ws *Listener) SetAuthedPubkey(b []byte)
- func (ws *Listener) SetChallenge(b []byte)
- func (ws *Listener) SetPendingEvent(ev *event.E)
- func (ws *Listener) Write(p []byte) (n int, err error)
- func (ws *Listener) WriteJSON(any interface{}) error
- func (ws *Listener) WriteMessage(t int, b []byte) error
- type PoolOption
- type PublishResult
- type RelayEvent
- type RelayOption
- type ReplaceableKey
- type SimplePool
- func (pool *SimplePool) BatchedSubManyEose(ctx context.T, dfs []DirectedFilter, opts ...SubscriptionOption) chan RelayEvent
- func (pool *SimplePool) Close(reason string)
- func (pool *SimplePool) EnsureRelay(url string) (*Client, error)
- func (pool *SimplePool) FetchMany(ctx context.T, urls []string, filter *filter.F, opts ...SubscriptionOption) chan RelayEvent
- func (pool *SimplePool) FetchManyReplaceable(ctx context.T, urls []string, filter *filter.F, opts ...SubscriptionOption) *xsync.MapOf[ReplaceableKey, *event.E]
- func (pool *SimplePool) PublishMany(ctx context.T, urls []string, evt *event.E) chan PublishResult
- func (pool *SimplePool) QuerySingle(ctx context.T, urls []string, filter *filter.F, opts ...SubscriptionOption) *RelayEvent
- func (pool *SimplePool) SubMany(ctx context.T, urls []string, filters *filters.T, opts ...SubscriptionOption) chan RelayEventdeprecated
- func (pool *SimplePool) SubManyEose(ctx context.T, urls []string, filters *filters.T, opts ...SubscriptionOption) chan RelayEventdeprecated
- func (pool *SimplePool) SubscribeMany(ctx context.T, urls []string, filter *filter.F, opts ...SubscriptionOption) chan RelayEvent
- func (pool *SimplePool) SubscribeManyNotifyEOSE(ctx context.T, urls []string, filter *filter.F, eoseChan chan struct{}, ...) chan RelayEvent
- type Subscription
- type SubscriptionOption
- type WithAuthHandler
- type WithAuthMiddleware
- type WithAuthorKindQueryMiddleware
- type WithCheckDuplicate
- type WithCheckDuplicateReplaceable
- type WithCustomHandler
- type WithDuplicateMiddleware
- type WithEventMiddleware
- type WithLabel
- type WithRequestHeader
Constants ¶
const MAX_LOCKS = 50
Variables ¶
This section is empty.
Functions ¶
func WithPenaltyBox ¶ added in v0.5.0
func WithPenaltyBox() withPenaltyBoxOpt
WithPenaltyBox just sets the penalty box mechanism so relays that fail to connect or that disconnect will be ignored for a while and we won't attempt to connect again.
func WithRelayOptions ¶ added in v0.5.0
func WithRelayOptions(ropts ...RelayOption) withRelayOptionsOpt
WithRelayOptions sets options that will be used on every relay instance created by this pool.
Types ¶
type Client ¶
type Client struct {
URL string
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
}
Client represents a connection to a Nostr relay.
func NewRelay ¶
func NewRelay(ctx context.Context, url string, opts ...RelayOption) *Client
NewRelay returns a new relay. It takes a context that, when canceled, will close the relay connection.
func RelayConnect ¶
RelayConnect returns a relay object connected to url.
The given subscription is only used during the connection phase. Once successfully connected, cancelling ctx has no effect.
The ongoing relay connection uses a background context. To close the connection, call r.Close(). If you need fine grained long-term connection contexts, use NewRelay() instead.
func (*Client) Auth ¶
Auth sends an "AUTH" command client->relay as in NIP-42 and waits for an OK response.
You don't have to build the AUTH event yourself, this function takes a function to which the event that must be signed will be passed, so it's only necessary to sign that.
func (*Client) 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 given context here is only used during the connection phase. The long-living relay connection will be based on the context given to NewRelay().
func (*Client) ConnectWithTLS ¶
ConnectWithTLS is like Connect(), but takes a special tls.Config if you need that.
func (*Client) Context ¶
Context retrieves the context that is associated with this relay connection. It will be closed when the relay is disconnected.
func (*Client) IsConnected ¶
IsConnected returns true if the connection to this relay seems to be active.
func (*Client) PrepareSubscription ¶
func (r *Client) PrepareSubscription( ctx context.Context, ff *filters.T, opts ...SubscriptionOption, ) (sub *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 (*Client) Publish ¶
Publish sends an "EVENT" command to the relay r as in NIP-01 and waits for an OK response.
func (*Client) QueryEvents ¶ added in v0.5.0
QueryEvents subscribes to events matching the given filter and returns a channel of events.
In most cases it's better to use SimplePool instead of this method.
func (*Client) QuerySync ¶
QuerySync subscribes to events matching the given filter and returns a slice of events. This method blocks until all events are received or the context is canceled.
In most cases it's better to use SimplePool instead of this method.
func (*Client) Subscribe ¶
func (r *Client) Subscribe( ctx context.Context, ff *filters.T, 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 Connection ¶
type Connection struct {
// contains filtered or unexported fields
}
Connection represents a websocket connection to a Nostr relay.
func NewConnection ¶
func NewConnection( ctx context.T, url string, reqHeader http.Header, tlsConfig *tls.Config, ) (c *Connection, err error)
NewConnection creates a new websocket connection to a Nostr relay.
func (*Connection) Close ¶
func (c *Connection) Close() error
Close closes the websocket connection.
func (*Connection) Ping ¶ added in v0.5.0
func (c *Connection) Ping(ctx context.T) error
Ping sends a ping message to the websocket connection.
func (*Connection) ReadMessage ¶
ReadMessage reads arbitrary bytes from the websocket connection into the provided buffer.
func (*Connection) WriteMessage ¶
func (c *Connection) WriteMessage( ctx context.T, data []byte, ) (err error)
WriteMessage writes arbitrary bytes to the websocket connection.
type DirectedFilter ¶ added in v0.5.0
DirectedFilter combines a Filter with a specific relay URL.
type Listener ¶
type Listener struct {
Conn *websocket.Conn
Request *http.Request
// contains filtered or unexported fields
}
Listener is a websocket implementation for a relay listener.
func NewListener ¶
NewListener creates a new Listener for listening for inbound connections for a relay.
func (*Listener) AuthRequested ¶
AuthRequested returns whether the Listener has asked for auth from the client.
func (*Listener) AuthedPubkey ¶
func (*Listener) GetPendingEvent ¶ added in v0.2.18
func (*Listener) RealRemote ¶
RealRemote returns the stored remote address of the client.
func (*Listener) Req ¶
Req returns the http.Request associated with the client connection to the Listener.
func (*Listener) RequestAuth ¶
func (ws *Listener) RequestAuth()
RequestAuth stores when auth has been required from a client.
func (*Listener) SetAuthedPubkey ¶
func (*Listener) SetChallenge ¶
func (*Listener) SetPendingEvent ¶ added in v0.2.18
type PoolOption ¶
type PoolOption interface {
ApplyPoolOption(*SimplePool)
}
PoolOption is an interface for options that can be applied to a SimplePool.
type PublishResult ¶ added in v0.5.0
PublishResult represents the result of publishing an event to a relay.
type RelayEvent ¶ added in v0.5.0
RelayEvent represents an event received from a specific relay.
func (RelayEvent) String ¶ added in v0.5.0
func (ie RelayEvent) String() string
type RelayOption ¶
type RelayOption interface {
ApplyRelayOption(*Client)
}
RelayOption is the type of the argument passed when instantiating relay connections.
type ReplaceableKey ¶ added in v0.5.0
type SimplePool ¶ added in v0.8.1
type SimplePool struct {
Relays *xsync.MapOf[string, *Client]
Context context.T
// contains filtered or unexported fields
}
SimplePool manages connections to multiple relays, ensures they are reopened when necessary and not duplicated.
func NewSimplePool ¶ added in v0.8.1
func NewSimplePool(ctx context.T, opts ...PoolOption) *SimplePool
NewSimplePool creates a new SimplePool with the given context and options.
func (*SimplePool) BatchedSubManyEose ¶ added in v0.8.1
func (pool *SimplePool) BatchedSubManyEose( ctx context.T, dfs []DirectedFilter, opts ...SubscriptionOption, ) chan RelayEvent
BatchedSubManyEose performs batched subscriptions to multiple relays with different filters.
func (*SimplePool) Close ¶ added in v0.8.1
func (pool *SimplePool) Close(reason string)
Close closes the pool with the given reason.
func (*SimplePool) EnsureRelay ¶ added in v0.8.1
func (pool *SimplePool) EnsureRelay(url string) (*Client, error)
EnsureRelay ensures that a relay connection exists and is active. If the relay is not connected, it attempts to connect.
func (*SimplePool) FetchMany ¶ added in v0.8.1
func (pool *SimplePool) FetchMany( ctx context.T, urls []string, filter *filter.F, opts ...SubscriptionOption, ) chan RelayEvent
FetchMany opens a subscription, much like SubscribeMany, but it ends as soon as all Relays return an EOSE message.
func (*SimplePool) FetchManyReplaceable ¶ added in v0.8.1
func (pool *SimplePool) FetchManyReplaceable( ctx context.T, urls []string, filter *filter.F, opts ...SubscriptionOption, ) *xsync.MapOf[ReplaceableKey, *event.E]
FetchManyReplaceable is like FetchMany, but deduplicates replaceable and addressable events and returns only the latest for each "d" tag.
func (*SimplePool) PublishMany ¶ added in v0.8.1
func (pool *SimplePool) PublishMany( ctx context.T, urls []string, evt *event.E, ) chan PublishResult
PublishMany publishes an event to multiple relays and returns a channel of results emitted as they're received.
func (*SimplePool) QuerySingle ¶ added in v0.8.1
func (pool *SimplePool) QuerySingle( ctx context.T, urls []string, filter *filter.F, opts ...SubscriptionOption, ) *RelayEvent
QuerySingle returns the first event returned by the first relay, cancels everything else.
func (*SimplePool) SubMany
deprecated
added in
v0.8.1
func (pool *SimplePool) SubMany( ctx context.T, urls []string, filters *filters.T, opts ...SubscriptionOption, ) chan RelayEvent
Deprecated: SubMany is deprecated: use SubscribeMany instead.
func (*SimplePool) SubManyEose
deprecated
added in
v0.8.1
func (pool *SimplePool) SubManyEose( ctx context.T, urls []string, filters *filters.T, opts ...SubscriptionOption, ) chan RelayEvent
Deprecated: SubManyEose is deprecated: use FetchMany instead.
func (*SimplePool) SubscribeMany ¶ added in v0.8.1
func (pool *SimplePool) SubscribeMany( ctx context.T, urls []string, filter *filter.F, opts ...SubscriptionOption, ) chan RelayEvent
SubscribeMany opens a subscription with the given filter to multiple relays the subscriptions ends when the context is canceled or when all relays return a CLOSED.
func (*SimplePool) SubscribeManyNotifyEOSE ¶ added in v0.8.1
func (pool *SimplePool) SubscribeManyNotifyEOSE( ctx context.T, urls []string, filter *filter.F, eoseChan chan struct{}, opts ...SubscriptionOption, ) chan RelayEvent
SubscribeManyNotifyEOSE is like SubscribeMany, but takes a channel that is closed when all subscriptions have received an EOSE
type Subscription ¶
type Subscription struct {
Client *Client
Filters *filters.T
// the Events channel emits all EVENTs that come in a Subscription
// will be closed when the subscription ends
Events chan *event.E
// 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
}
Subscription represents a subscription to a relay.
func (*Subscription) Close ¶
func (sub *Subscription) Close()
Close just sends a CLOSE message. You probably want Unsub() instead.
func (*Subscription) Fire ¶
func (sub *Subscription) Fire() (err error)
Fire sends the "REQ" command to the relay.
func (*Subscription) GetID ¶
func (sub *Subscription) GetID() string
GetID returns the subscription ID.
func (*Subscription) Sub ¶
func (sub *Subscription) Sub(_ context.Context, ff *filters.T)
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 ¶
type SubscriptionOption interface {
IsSubscriptionOption()
}
SubscriptionOption is the type of the argument passed when instantiating relay connections. Some examples are WithLabel.
type WithAuthHandler ¶
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) ApplyPoolOption ¶
func (h *WithAuthHandler) ApplyPoolOption(pool *SimplePool)
type WithAuthMiddleware ¶ added in v0.8.1
type WithAuthMiddleware func(RelayEvent) error
type WithAuthorKindQueryMiddleware ¶ added in v0.5.0
WithAuthorKindQueryMiddleware is a function that will be called with every combination of relay+pubkey+kind queried in a .SubMany*() call -- when applicable (i.e. when the query contains a pubkey and a kind).
func (WithAuthorKindQueryMiddleware) ApplyPoolOption ¶ added in v0.5.0
func (h WithAuthorKindQueryMiddleware) ApplyPoolOption(pool *SimplePool)
type WithCheckDuplicate ¶ added in v0.8.1
WithCheckDuplicate sets checkDuplicate on the subscription
func (WithCheckDuplicate) IsSubscriptionOption ¶ added in v0.8.1
func (_ WithCheckDuplicate) IsSubscriptionOption()
type WithCheckDuplicateReplaceable ¶ added in v0.8.1
type WithCheckDuplicateReplaceable func(rk ReplaceableKey, ts *timestamp.T) bool
WithCheckDuplicateReplaceable sets checkDuplicateReplaceable on the subscription
func (WithCheckDuplicateReplaceable) IsSubscriptionOption ¶ added in v0.8.1
func (_ WithCheckDuplicateReplaceable) IsSubscriptionOption()
type WithCustomHandler ¶ added in v0.5.0
type WithCustomHandler func(data string)
WithCustomHandler must be a function that handles any relay message that couldn't be parsed as a standard envelope.
func (WithCustomHandler) ApplyRelayOption ¶ added in v0.5.0
func (ch WithCustomHandler) ApplyRelayOption(r *Client)
type WithDuplicateMiddleware ¶ added in v0.5.0
WithDuplicateMiddleware is a function that will be called with all duplicate ids received.
func (WithDuplicateMiddleware) ApplyPoolOption ¶ added in v0.5.0
func (h WithDuplicateMiddleware) ApplyPoolOption(pool *SimplePool)
type WithEventMiddleware ¶
type WithEventMiddleware func(RelayEvent)
WithEventMiddleware is a function that will be called with all events received.
func (WithEventMiddleware) ApplyPoolOption ¶
func (h WithEventMiddleware) ApplyPoolOption(pool *SimplePool)
type WithLabel ¶
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 ¶
func (_ WithLabel) IsSubscriptionOption()
type WithRequestHeader ¶ added in v0.5.0
WithRequestHeader sets the HTTP request header of the websocket preflight request.
func (WithRequestHeader) ApplyRelayOption ¶ added in v0.5.0
func (ch WithRequestHeader) ApplyRelayOption(r *Client)