client

package
v0.2.4 Latest Latest
Warning

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

Go to latest
Published: Jul 21, 2026 License: Unlicense Imports: 14 Imported by: 0

Documentation

Overview

Package client is a Nostr relay WebSocket client: dial a relay (Connection), publish and subscribe, and round-trip higher-level protocols built on top of the wire format (e.g. NWCClient for NIP-47). It wraps the wire and nip01 packages so callers don't need to handle raw relay packets directly.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrConnectionClosed = errors.New("connection closed")
)

Functions

func NewConnectionError

func NewConnectionError(relay *url.URL, message string, err error) error

func PublishEventToRelay added in v0.2.2

func PublishEventToRelay(ctx context.Context, relayURL *url.URL, ev *nip01.Event) (*wire.OkSubscriptionResponse, error)

PublishEventToRelay dials relayURL, publishes ev, and waits for the relay's OK response, closing the connection afterward. This is the one-shot form for a single publish; for multiple publishes over one connection, dial with NewConnection and call Publish directly.

func ReadEventsFromRelay

func ReadEventsFromRelay(parent context.Context, relayURL *url.URL, filters *nip01.SubscriptionFilterGroup) ([]*nip01.Event, error)

func ReadEventsFromStore

func ReadEventsFromStore(parent context.Context, path string, filters *nip01.SubscriptionFilterGroup) ([]*nip01.Event, error)

Types

type Connection

type Connection struct {
	// contains filtered or unexported fields
}

func Connect added in v0.2.2

func Connect(ctx context.Context, relayURL *url.URL) (*Connection, error)

Connect dials relayURL with default timeouts and intervals. This is the common path — for custom handshake/ping/write timeouts, use NewConnection with an explicit *ConnectionConfig instead.

func NewConnection

func NewConnection(ctx context.Context, relayURL *url.URL, cfg *ConnectionConfig) (*Connection, error)

func (*Connection) Close

func (c *Connection) Close()

func (*Connection) CloseSubscription

func (c *Connection) CloseSubscription(subID string) bool

func (*Connection) Closed

func (c *Connection) Closed() <-chan interface{}

func (*Connection) Errors

func (c *Connection) Errors() <-chan error

func (*Connection) Events added in v0.2.2

func (c *Connection) Events(subID string) <-chan *wire.EventSubscriptionResponse

Events filters Read()'s shared channel down to EVENT messages for one subscription ID (or all, if subID is ""). Advanced: pairs with SubscribeWithID when you need to retain manual control of the subscription ID; for the common case, use Subscribe instead, which doesn't require also consuming Read() yourself.

func (*Connection) Outgoing

func (c *Connection) Outgoing() chan<- interface{}

Outgoing exposes the raw outgoing packet channel for packet types (e.g. NIP-77 negentropy packets) that don't have a dedicated semantic method above.

func (*Connection) Publish added in v0.2.2

Publish sends ev and blocks until the relay responds OK for this event's ID, ctx is cancelled, or the connection errors/closes. This is the common path for "did my event make it." For fire-and-forget with no acceptance confirmation, use Send. Publish consumes from the same shared channel as Read(), so don't run it concurrently with your own Read() loop on the same Connection.

func (*Connection) Read

func (c *Connection) Read() <-chan wire.SubscriptionResponse

Read returns the shared channel of every incoming message type for every subscription on this connection — the advanced, un-demultiplexed view. For the common case of "just the events for one subscription," use Subscribe or Events instead.

func (*Connection) Relay added in v0.2.2

func (c *Connection) Relay() *url.URL

Relay reports the URL this connection was dialed against.

func (*Connection) Send

func (c *Connection) Send(ev *nip01.Event) bool

func (*Connection) Subscribe

func (c *Connection) Subscribe(filter *nip01.SubscriptionFilterGroup) (subID string, events <-chan *wire.EventSubscriptionResponse, done <-chan struct{})

Subscribe opens a subscription and returns its ID plus a typed channel of just this subscription's EVENT messages, closing both the events and done channels at EOSE, at CLOSED, or when the connection closes. This is the common path for "give me the events for this filter." For a long-lived subscription that must keep receiving events past EOSE, or for manual control over the subscription ID and access to every message type/subscription on the connection, use SubscribeWithID + Read instead — don't mix the two consumption styles on the same Connection concurrently.

func (*Connection) SubscribeWithID

func (c *Connection) SubscribeWithID(subID string, filter *nip01.SubscriptionFilterGroup) bool

type ConnectionConfig

type ConnectionConfig struct {
	HandshakeTimeout time.Duration
	PingInterval     time.Duration
	PongTimeout      time.Duration
	WriteTimeout     time.Duration
}

func DefaultConnectionConfig

func DefaultConnectionConfig() *ConnectionConfig

type ConnectionError

type ConnectionError struct {
	Relay   *url.URL
	Message string
	Origin  error
}

func (*ConnectionError) Error

func (ce *ConnectionError) Error() string

func (*ConnectionError) Unwrap

func (ce *ConnectionError) Unwrap() error

type MultiPayInvoiceResult added in v0.2.2

type MultiPayInvoiceResult struct {
	Id     string
	Result *nip47.PayInvoiceResult
	Error  *nip47.Error
}

MultiPayInvoiceResult is one sub-payment's outcome from MultiPayInvoice: exactly one of Result or Error is set, correlated back to the request item via its Id (MultiPayInvoiceItem.Id).

type MultiPayKeysendResult added in v0.2.2

type MultiPayKeysendResult struct {
	Id     string
	Result *nip47.PayKeysendResult
	Error  *nip47.Error
}

MultiPayKeysendResult is one sub-payment's outcome from MultiPayKeysend: exactly one of Result or Error is set, correlated back to the request item via its Id (MultiPayKeysendItem.Id).

type NWCClient added in v0.2.2

type NWCClient struct {
	// contains filtered or unexported fields
}

NWCClient is a NIP-47 (Nostr Wallet Connect) client bound to one pairing. It holds a single persistent WebSocket connection to the wallet's relay, reused across every call, and a background dispatcher that demultiplexes concurrent in-flight calls by subscription ID. Safe for concurrent use by multiple goroutines. Construct with NewNWCClient and release resources with Close when done.

func NewNWCClient added in v0.2.2

func NewNWCClient(ctx context.Context, pairing *nip47.PairingInfo, encryption string) (*NWCClient, error)

NewNWCClient parses pairing.RelayURLs[0] (only the first relay is used) and dials it, then starts a background dispatcher that owns the connection's incoming messages for the client's entire lifetime. encryption selects the request/response scheme (nip47.EncryptionNIP04 or nip47.EncryptionNIP44V2); "" defaults to nip47.EncryptionNIP44V2.

ctx is only used for an up-front cancellation check — it is deliberately not threaded into the dial as the connection's lifetime context, since Connect's ctx parameter tears the connection down on cancellation, which would be a footgun for a client meant to be held and reused long-term. Close is the only way to end the connection's life.

func (*NWCClient) Call added in v0.2.2

func (c *NWCClient) Call(ctx context.Context, method string, params any) (*nip47.ResponseEvent, error)

Call sends method with params and returns the raw parsed response envelope — SubPaymentID, RequestEventID, and Response.Error verbatim, without converting a wallet decline into a Go error — the caller inspects resp.Error themselves. Use this for wallet-specific/nonstandard methods not covered by the typed methods above. It waits for exactly one response event; it is not suitable for fan-out under a non-standard method name.

func (*NWCClient) CancelHoldInvoice added in v0.2.2

func (c *NWCClient) CancelHoldInvoice(ctx context.Context, params nip47.CancelHoldInvoiceParams) error

CancelHoldInvoice cancels a hold invoice.

func (*NWCClient) Close added in v0.2.2

func (c *NWCClient) Close()

Close closes the underlying connection and fails every in-flight and any future call with a terminal error. Blocks until the dispatcher goroutine has fully exited, so no goroutine is left running after Close returns. Safe to call more than once and safe to call concurrently with in-flight calls.

func (*NWCClient) GetBalance added in v0.2.2

func (c *NWCClient) GetBalance(ctx context.Context) (*nip47.GetBalanceResult, error)

GetBalance returns the wallet's current balance.

func (*NWCClient) GetBudget added in v0.2.2

func (c *NWCClient) GetBudget(ctx context.Context) (*nip47.GetBudgetResult, error)

GetBudget returns the connection's budget status.

func (*NWCClient) GetInfo added in v0.2.2

func (c *NWCClient) GetInfo(ctx context.Context) (*nip47.GetInfoResult, error)

GetInfo returns the wallet's capabilities and node info.

func (*NWCClient) ListTransactions added in v0.2.2

ListTransactions lists past transactions.

func (*NWCClient) LookupInvoice added in v0.2.2

func (c *NWCClient) LookupInvoice(ctx context.Context, params nip47.LookupInvoiceParams) (*nip47.Transaction, error)

LookupInvoice looks up an invoice by payment hash or invoice string.

func (*NWCClient) MakeHoldInvoice added in v0.2.2

func (c *NWCClient) MakeHoldInvoice(ctx context.Context, params nip47.MakeHoldInvoiceParams) (*nip47.Transaction, error)

MakeHoldInvoice creates a new hold invoice.

func (*NWCClient) MakeInvoice added in v0.2.2

func (c *NWCClient) MakeInvoice(ctx context.Context, params nip47.MakeInvoiceParams) (*nip47.Transaction, error)

MakeInvoice creates a new BOLT11 invoice.

func (*NWCClient) MultiPayInvoice added in v0.2.2

func (c *NWCClient) MultiPayInvoice(ctx context.Context, params nip47.MultiPayInvoiceParams) ([]MultiPayInvoiceResult, error)

MultiPayInvoice pays multiple BOLT11 invoices in one request, waiting for every sub-payment's response event or ctx.Done(), whichever first. On full success every params.Invoices item has a corresponding entry (in request order) with either Result or Error set — a per-item wallet decline does not fail the overall call. On partial completion (ctx expires or the connection dies before every sub-payment answered) it returns whatever was collected so far, in request order, together with a non-nil error.

func (*NWCClient) MultiPayKeysend added in v0.2.2

func (c *NWCClient) MultiPayKeysend(ctx context.Context, params nip47.MultiPayKeysendParams) ([]MultiPayKeysendResult, error)

MultiPayKeysend pays multiple keysend payments in one request. See MultiPayInvoice for collection semantics.

func (*NWCClient) PayInvoice added in v0.2.2

func (c *NWCClient) PayInvoice(ctx context.Context, params nip47.PayInvoiceParams) (*nip47.PayInvoiceResult, error)

PayInvoice pays a BOLT11 invoice.

func (*NWCClient) PayKeysend added in v0.2.2

func (c *NWCClient) PayKeysend(ctx context.Context, params nip47.PayKeysendParams) (*nip47.PayKeysendResult, error)

PayKeysend pays a keysend payment.

func (*NWCClient) SettleHoldInvoice added in v0.2.2

func (c *NWCClient) SettleHoldInvoice(ctx context.Context, params nip47.SettleHoldInvoiceParams) error

SettleHoldInvoice settles a hold invoice.

func (*NWCClient) SignMessage added in v0.2.2

func (c *NWCClient) SignMessage(ctx context.Context, params nip47.SignMessageParams) (*nip47.SignMessageResult, error)

SignMessage asks the wallet to sign an arbitrary message.

type WalletError added in v0.2.2

type WalletError struct {
	Method  string
	Code    string
	Message string
}

WalletError is returned when a wallet service declines a NIP-47 request (the response's Error field is set). Method is the NIP-47 method name that was called (e.g. nip47.MethodPayInvoice). Use errors.As to recover the wallet's Code/Message instead of matching on the error string.

func (*WalletError) Error added in v0.2.2

func (e *WalletError) Error() string

Jump to

Keyboard shortcuts

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