RelayManager<T> class

relay manager, responsible for lifecycle of relays, sending messages,
and help with tracking of requests

Constructors

RelayManager({required GlobalState globalState, required NostrTransportFactory nostrTransportFactory, Accounts? accounts, EngineAdditionalDataFactory? engineAdditionalDataFactory, List<String>? bootstrapRelays, dynamic allowReconnect = true, Duration authCallbackTimeout = RequestDefaults.DEFAULT_AUTH_CALLBACK_TIMEOUT, Duration authChallengeTimeout = RequestDefaults.DEFAULT_AUTH_CHALLENGE_TIMEOUT})
Creates a new relay manager.

Properties

allowReconnectRelays ↔ bool
Are reconnects allowed when a connection drops?
getter/setter pair
authCallbackTimeout → Duration
timeout for AUTH callbacks (how long to wait for AUTH OK)
final
authChallengeTimeout → Duration
how long to wait for a NIP-42 challenge once authentication was asked for
final
connectedAnonymousRelays → List<RelayConnectivity>
Connected connections bound to nobody, one per relay at most.
no setter
connectedRelays → List<RelayConnectivity>
Returns a list of fully connected relays, excluding connecting ones. DO NOT USE THIS FOR CHECKING A SINGLE RELAY, use isRelayConnected INSTEAD
no setter
engineAdditionalDataFactory → EngineAdditionalDataFactory?
factory for creating additional data for the engine
final
globalState ↔ GlobalState
global state obj
getter/setter pair
hashCode → int
The hash code for this object.
no setterinherited
nostrTransportFactory → NostrTransportFactory
nostr transport factory, to create new transports (usually websocket)
final
onNegClosed ↔ void Function(String subscriptionId, RelayConnectionKey key, String? message)?
Handler for CLOSED messages that end a NIP-77 negotiation
getter/setter pair
onNegErr ↔ void Function(String subscriptionId, RelayConnectionKey key, String errorMsg)?
Handler for NIP-77 NEG-ERR messages
getter/setter pair
onNegMsg ↔ void Function(String subscriptionId, RelayConnectionKey key, String errorMsg)?
Handler for NIP-77 NEG-MSG messages
getter/setter pair
relayConnectivityChanges → Stream<List<RelayConnectivity>>
stream of connection updates, used to notify connectivity changes, latest value is cached. A relay can hold several connections, so this cannot be indexed by url; group by RelayConnectivity.url if you need to.
no setter
runtimeType → Type
A representation of the runtime type of the object.
no setterinherited
seedRelaysConnected → Future<void>
completes when all seed relays are connected
no setter

Methods

accountForAuth(AuthPolicy? auth) → Account?
Account auth authenticates as, null when it must stay unattributable.
authenticateConnection(RelayConnectionKey key) → Future<bool>
Answers the challenge for key and completes once the relay accepted the AUTH event. Concurrent callers share a single AUTH.
authenticateIfNeeded(String relayUrl, List<Account> accounts) → void
Opens the bound connections a subscription will need, so the re-route on auth-required does not have to open a socket first.
beginPendingConnection(RequestState state) → void
Announces a send path that has yet to work out which connection to use, so a relay answering meanwhile does not look like the only one this request ever had. Pair every call with endPendingConnection.
closeAllTransports() → Future<void>
Closes all transports
closeConnection(RelayConnectionKey key) → Future<void>
Closes one connection and forgets it. An entry that lost its transport, to a reset or to a failed connection attempt, is forgotten just the same: leaving it behind keeps its auth state alive and makes it reconnect.
closeTransport(String url) → Future<void>
Closes every connection towards url and forgets them
connectionForBroadcast(String url, AuthPolicy? auth, {ConnectionSource connectionSource = ConnectionSource.broadcastSpecific, int connectTimeout = DEFAULT_WEB_SOCKET_CONNECT_TIMEOUT}) → Future<RelayConnectivity?>
The connection a broadcast under auth must go out on towards url, opening it when it is not there yet. Null means nothing may be sent.
connectionForRequest(RequestState state, RelayConnectivity picked, {ConnectionSource connectionSource = ConnectionSource.explicit}) → Future<RelayConnectivity?>
The connection state must go out on towards the relay an engine picked.
connectRelay({required String dirtyUrl, required ConnectionSource connectionSource, String? authPubkey, int connectTimeout = DEFAULT_WEB_SOCKET_CONNECT_TIMEOUT}) → Future<Tuple<bool, String>>
Connects to a relay to the relay pool. Returns a tuple with the first element being a boolean indicating success \ and the second element being a string with the error message if any.
doesRelaySupportNip(String url, int nip) → bool
does relay support given nip
endPendingConnection(RequestState state) → void
Ends what beginPendingConnection announced, and reconsiders closing the request. A path that gave up without registering anything is the last thing that can notice: nothing else runs when a connection simply never opened.
failBroadcast(String nostrEventId, String relay, String msg) → void
use this to signal a failed broadcast
getConnectivity(RelayConnectionKey key) → RelayConnectivity?
return RelayConnectivity of one connection, anonymous or bound
getRelayConnectivity(String url) → RelayConnectivity?
return RelayConnectivity by url
getRelayInfo(String url) → Future<RelayInfo?>
fetches relay info todo: refactor to use http injector and decouple data from fetching
isConnectionConnecting(RelayConnectionKey key) → bool
checks if the connection identified by key is connecting
isConnectionOpen(RelayConnectionKey key) → bool
checks if the connection identified by key is open
isRelayConnected(String url) → bool
checks if a relay is connected, avoid using this
isRelayConnecting(String url) → bool
checks if a relay is connecting
isStillInFlight(RequestState state) → bool
Whether state is still tracked, see _isStillInFlight. Engines must ask before sending anything they resolved across an await: a timeout or a Requests.closeSubscription may have ended the request in between.
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
openConnectionAs(String url, Account account, {ConnectionSource connectionSource = ConnectionSource.explicit, int connectTimeout = DEFAULT_WEB_SOCKET_CONNECT_TIMEOUT}) → Future<RelayConnectivity?>
Opens the connection towards url bound to account. The binding says which identity this socket may ever assume, not that it is already authenticated: relays are free to send their challenge whenever they want, and some only send it once a request needs it.
reconnectConnection(RelayConnectionKey key, {required ConnectionSource connectionSource, bool force = false, Account? as}) → Future<bool>
Reconnects the connection identified by key, if it is closed. An authenticated connection comes back authenticated or not at all.
reconnectRelay(String url, {required ConnectionSource connectionSource, bool force = false}) → Future<bool>
Reconnects the anonymous connection to a relay, if it is closed.
reconnectRelays(Iterable<String> urls) → Future<void>
Reconnects all given relays
registerRelayBroadcast({required String relayUrl, required Nip01Event eventToPublish}) → void
use this to register your broadcast against a relay,
this is needed so the response from a relay can be tracked back
registerRelayRequest({required String reqId, required RelayConnectionKey connectionKey, required List<Filter> filters}) → void
use this to register your request against a relay,
this is needed so the response from a relay can be tracked back
resetConnection(RelayConnectionKey key) → Future<void>
Closes and clears only transport-scoped state of one connection, while keeping its entry and relay-scoped metadata in memory.
resetTransport(String url) → Future<void>
Closes and clears only transport-scoped state of every connection to url, while keeping the entries and relay-scoped metadata in memory.
reSubscribeInFlightSubscriptions(RelayConnectivity relayConnectivity) → void
Puts back on relayConnectivity what the socket it replaces still owed us: its subscriptions, and the queries that never got their EOSE.
send(RelayConnectivity relayConnectivity, ClientMsg msg) → void
sends a ClientMsg to relay transport sink, throw an error if relay not connected
sendCloseToConnection(RelayConnectionKey key, String id) → void
sends a close message on the connection the subscription was sent on
sendCloseToRelay(String url, String id) → void
sends a close message on the anonymous connection to a relay
sendOrThrow(RelayConnectivity relayConnectivity, ClientMsg msg) → Future<void>
Sends a ClientMsg and surfaces transport churn/closed-socket failures to the caller instead of silently dropping the write.
toString() → String
A string representation of this object.
inherited
updateRelayConnectivity() → void

Operators

operator ==(Object other) → bool
The equality operator.
inherited