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.T, sign signer.I) (err error)
- func (r *Client) Close() error
- func (r *Client) Connect(ctx context.T) error
- func (r *Client) ConnectWithTLS(ctx context.T, tlsConfig *tls.Config) (err error)
- func (r *Client) Context() context.T
- func (r *Client) IsConnected() bool
- func (r *Client) PrepareSubscription(ctx context.T, ff *filters.T, opts ...SubscriptionOption) *Subscription
- func (r *Client) Publish(ctx context.T, ev *event.E) error
- func (r *Client) QueryEvents(ctx context.T, f *filter.F) (evc event.C, err error)
- func (r *Client) QuerySync(ctx context.T, f *filter.F) (evs event.S, err error)
- func (r *Client) String() string
- func (r *Client) Subscribe(ctx context.T, ff *filters.T, opts ...SubscriptionOption) (sub *Subscription, err 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 Pool
- func (p *Pool) BatchedSubManyEose(ctx context.T, dfs []DirectedFilter, opts ...SubscriptionOption) chan RelayEvent
- func (p *Pool) Close(reason string)
- func (p *Pool) EnsureRelay(url string) (*Client, error)
- func (p *Pool) FetchMany(ctx context.T, urls []string, filter *filter.F, opts ...SubscriptionOption) chan RelayEvent
- func (p *Pool) FetchManyReplaceable(ctx context.T, urls []string, f *filter.F, opts ...SubscriptionOption) *xsync.MapOf[ReplaceableKey, *event.E]
- func (p *Pool) QuerySingle(ctx context.T, urls []string, filter *filter.F, opts ...SubscriptionOption) *RelayEvent
- func (p *Pool) SubMany(ctx context.T, urls []string, filters *filters.T, opts ...SubscriptionOption) chan RelayEventdeprecated
- func (p *Pool) SubManyEose(ctx context.T, urls []string, filters *filters.T, opts ...SubscriptionOption) chan RelayEventdeprecated
- func (p *Pool) SubscribeMany(ctx context.T, urls []string, filter *filter.F, opts ...SubscriptionOption) chan RelayEvent
- func (p *Pool) SubscribeManyNotifyEOSE(ctx context.T, urls []string, filter *filter.F, eoseChan chan struct{}, ...) chan RelayEvent
- type PoolOption
- type PublishResult
- type RelayEvent
- type RelayOption
- type ReplaceableKey
- type Subscription
- type SubscriptionOption
- type WithAuthHandler
- type WithAuthorKindQueryMiddleware
- type WithCustomHandler
- type WithDuplicateMiddleware
- type WithEventMiddleware
- type WithLabel
- type WithNoticeHandler
- 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[int64, *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
}
Relay represents a connection to a Nostr relay.
func NewRelay ¶
func NewRelay(ctx context.T, 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.
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.T, ff *filters.T, 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.T` 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 Pool 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.
If the filter causes a subscription to open, it will stay open until the limit is exceeded. So this method will return an error if the limit is nil. If the query blocks, the caller needs to cancel the context to prevent the thread stalling.
func (*Client) Subscribe ¶
func (r *Client) Subscribe( ctx context.T, ff *filters.T, opts ...SubscriptionOption, ) (sub *Subscription, err 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.T` 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.Context, url string, requestHeader http.Header, tlsConfig *tls.Config, ) (*Connection, 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.Context) 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.Context, data []byte) 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 Pool ¶
type Pool struct {
Relays *xsync.MapOf[string, *Client]
Context context.T
// contains filtered or unexported fields
}
Pool manages connections to multiple relays, ensures they are reopened when necessary and not duplicated.
func NewPool ¶
func NewPool(c context.T, opts ...PoolOption) (pool *Pool)
NewPool creates a new Pool with the given context and options.
func (*Pool) BatchedSubManyEose ¶
func (p *Pool) BatchedSubManyEose( ctx context.T, dfs []DirectedFilter, opts ...SubscriptionOption, ) chan RelayEvent
BatchedSubManyEose performs batched subscriptions to multiple relays with different filters.
func (*Pool) EnsureRelay ¶
EnsureRelay ensures that a relay connection exists and is active. If the relay is not connected, it attempts to connect.
func (*Pool) FetchMany ¶ added in v0.5.0
func (p *Pool) 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 (*Pool) FetchManyReplaceable ¶ added in v0.5.0
func (p *Pool) FetchManyReplaceable( ctx context.T, urls []string, f *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 (*Pool) QuerySingle ¶
func (p *Pool) 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 (*Pool) SubMany
deprecated
func (p *Pool) SubMany( ctx context.T, urls []string, filters *filters.T, opts ...SubscriptionOption, ) chan RelayEvent
Deprecated: SubMany is deprecated: use SubscribeMany instead.
func (*Pool) SubManyEose
deprecated
func (p *Pool) SubManyEose( ctx context.T, urls []string, filters *filters.T, opts ...SubscriptionOption, ) chan RelayEvent
Deprecated: SubManyEose is deprecated: use FetchMany instead.
func (*Pool) SubscribeMany ¶ added in v0.5.0
func (p *Pool) 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 (*Pool) SubscribeManyNotifyEOSE ¶ added in v0.5.0
func (p *Pool) 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 PoolOption ¶
type PoolOption interface {
ApplyPoolOption(*Pool)
}
PoolOption is an interface for options that can be applied to a Pool.
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 Subscription ¶
type Subscription struct {
Relay *Client
Filters *filters.T
// the Events channel emits all EVENTs that come in a Subscription
// will be closed when the subscription ends
Events event.C
// 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 *Pool)
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 *Pool)
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 *Pool)
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 *Pool)
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 WithNoticeHandler ¶
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) ApplyRelayOption ¶
func (nh WithNoticeHandler) ApplyRelayOption(r *Client)
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)