OfflineProtocol from @offline-protocol/mesh-sdk. These signatures match v0.27.0. Read the integration guide for prerequisites and complete usage.
Methods on this page
sendMessageforwardMessagesendConnectionRequestacceptConnectionRequestrejectConnectionRequestcancelConnectionRequestgetMessageStatsgetDeliverySuccessRategetMedianLatencygetMedianHopsreceiveMessagesendPresenceUpdatecheckInternetPresencesendTypingIndicatorsendReadReceiptblockUserunblockUsergetBlockedUsersisUserBlocked
sendMessage
Sends a message returns: Message ID throws: Error if message fails to sendforwardMessage
Forwards a message to a new recipient with original sender attribution. Creates a new message with the original content and attaches forwarding metadata tracking the original sender, message ID, timestamp, and forward count. returns: New message ID throws: Error if forwarding failssendConnectionRequest
Sends a connection requestparams.recipient must be the target’s canonical address (off1…): the value they derived from their own identity key, which is also what
neighbor_discovered reports as peer_id.
The returned message id is the correlation key for the request’s
outcome events: connection_request_undeliverable (recipient offline
or retry budget exhausted), message_delivered (reached the
recipient’s device), and message_failed (generic retry exhaustion,
fires alongside the typed event). The recipient’s answer arrives as
connection_accepted / connection_rejected, which correlate by peer
id (accepted_by / rejected_by), not by message id.
returns: Message ID
throws: Error if request fails to send
acceptConnectionRequest
Accepts a connection request returns: Message ID throws: Error if acceptance fails to sendrejectConnectionRequest
Rejects a connection request returns: Message ID throws: Error if rejection fails to sendcancelConnectionRequest
Cancels a previously sent connection request returns: Message ID throws: Error if cancellation fails to sendgetMessageStats
Gets message delivery statistics returns: Array of message delivery statistics throws: Error if stats retrieval failsgetDeliverySuccessRate
Gets the delivery success rate returns: Success rate as a number between 0 and 1 throws: Error if retrieval failsgetMedianLatency
Gets the median message delivery latency returns: Median latency in milliseconds, or null if no data available throws: Error if retrieval failsgetMedianHops
Gets the median hop count for delivered messages returns: Median hop count, or null if no data available throws: Error if retrieval failsreceiveMessage
Polls for the next received message returns: Message object if available, null otherwise throws: Error if polling failssendPresenceUpdate
Sends a presence update to a peer. returns: Message IDcheckInternetPresence
Asks the internet relay for a peer’s presence (one-shot CheckPresence).Contract
- Always fresh. The SDK never throttles or dedupes manual checks:
every accepted call sends a new
CheckPresenceframe to the relay, regardless of how recently the same peer was queried. (The automatic watch loop’s tick/TTL policy does not apply here.) - Fire-and-event. The answer arrives as a
presence_updatedevent withsource: 'internet'(includinglast_seen_mswhen the relay knows it) rather than in the returned promise. Every relay answer re-emits the event even when nothing changed: safe to drive a chat-header refresh from. Subscribe before calling; events have no replay. - Exceptions. The core suppresses presence for blocked peers and
your own user id: for those, this resolves
true(the query was sent) but nopresence_updatedfollows. Andtruemeans the query reached the socket, not that an answer will arrive: a connection dropped before the relay replies loses the answer (call again). - Rate limiting is never bypassed, force or not: the SDK’s client-side limiter mirrors the relay’s per-connection budget, and an over-budget frame would be dropped server-side after a locally “successful” write: strictly worse than deferring.
options.force is for chat open/focus: exactly when the app wants a
fresh header, the socket is often still resuming from background. A
non-forced call fails fast (false) in that window; a forced call is
parked and retried until the transport is authenticated and the
limiter admits it (up to ~8s), only then resolving false. On a
stopped transport (no reconnect coming) even forced calls fail fast.
Forced checks stay one-shot: they never join the SDK’s automatic
watch set.
returns: true once the socket accepted the query (write-confirmed on
iOS, enqueue-confirmed on Android, the closest OkHttp offers);
false otherwise, an empty userId (never sent), or not
connected+authenticated / rate-limiter-deferred past the
force deadline (non-forced: immediately; safe to retry)
throws: when the internet transport was never initialized (enable it via
transports.internet before calling)

