Skip to main content

Events Reference

Register listeners using protocol.on(eventType, listener). See Event Listeners for the full listener API.

Message Events

message_sent

interface MessageSentEvent {
  type: 'message_sent';
  message_id: string;
  sender: string;
  recipient: string;
  content: string;
  priority: 'low' | 'medium' | 'high' | 'critical';
  requires_ack: boolean;
  timestamp: number;
  lamport_clock: number;   // Causal ordering clock
  forward_info?: ForwardInfo;
}

message_received

interface MessageReceivedEvent {
  type: 'message_received';
  message_id: string;
  sender: string;
  recipient: string;
  content: string;
  hop_count: number;
  transport: string;
  timestamp: number;
  lamport_clock: number;
  encrypted?: boolean;          // Whether message was auto-decrypted
  content_type?: string;        // 'text', 'image', 'video', etc.
  media_metadata?: {
    mime_type?: string;
    file_name?: string;
    file_size?: number;
    duration_ms?: number;
    width?: number;
    height?: number;
    thumbnail_base64?: string;
  };
  forward_info?: ForwardInfo;
}

message_delivered

interface MessageDeliveredEvent {
  type: 'message_delivered';
  message_id: string;
  latency_ms: number;
  hop_count: number;
  transport: string;
}

message_failed

interface MessageFailedEvent {
  type: 'message_failed';
  message_id: string;
  reason: string;
  retry_count: number;
}

message_relayed

interface MessageRelayedEvent {
  type: 'message_relayed';
  message_id: string;
  sender: string;
  recipient: string;
  hop_count: number;
  remaining_ttl: number;
}

message_deferred

interface MessageDeferredEvent {
  type: 'message_deferred';
  message_id: string;
  reason: string;
  retry_count: number;
  next_retry_at?: number;
}

Connection Request Events

connection_request_received

interface ConnectionRequestReceivedEvent {
  type: 'connection_request_received';
  sender: string;
  sender_name: string;
  timestamp: number;
  key_package?: number[];
}

connection_accepted

interface ConnectionAcceptedEvent {
  type: 'connection_accepted';
  accepted_by: string;
  accepted_by_name: string;
  timestamp: number;
  key_package?: number[];
}

connection_rejected

interface ConnectionRejectedEvent {
  type: 'connection_rejected';
  rejected_by: string;
}

connection_request_cancelled

interface ConnectionRequestCancelledEvent {
  type: 'connection_request_cancelled';
  cancelled_by: string;
}

Network Events

transport_switched

interface TransportSwitchedEvent {
  type: 'transport_switched';
  from: string | null;
  to: string;
  reason: string;
}

neighbor_discovered

interface NeighborDiscoveredEvent {
  type: 'neighbor_discovered';
  peer_id: string;
  transport: string;
  rssi?: number;
}

neighbor_lost

interface NeighborLostEvent {
  type: 'neighbor_lost';
  peer_id: string;
}

network_metrics

interface NetworkMetricsEvent {
  type: 'network_metrics';
  neighbor_count: number;
  relay_count: number;
  delivery_ratio: number;
  avg_latency_ms: number;
}

Security Events

secure_session_established

interface SecureSessionEstablishedEvent {
  type: 'secure_session_established';
  peer_id: string;
  group_id: string;
  is_session: boolean;        // true for 1:1, false for group
  initiated_by_local: boolean;
}

secure_session_failed

interface SecureSessionFailedEvent {
  type: 'secure_session_failed';
  peer_id: string;
  reason: string;
}

welcome_send_attempted

interface WelcomeSendAttemptedEvent {
  type: 'welcome_send_attempted';
  peer_id: string;
  message_id: string;
  group_id: string;
  attempt: number;
}

welcome_send_succeeded

interface WelcomeSendSucceededEvent {
  type: 'welcome_send_succeeded';
  peer_id: string;
  message_id: string;
  group_id: string;
  attempt: number;
}

welcome_send_failed

interface WelcomeSendFailedEvent {
  type: 'welcome_send_failed';
  peer_id: string;
  message_id: string;
  group_id: string;
  attempt: number;
  reason_code: WelcomeReasonCode;
  transport_error?: string;
  retryable: boolean;
  next_retry_at?: number;
}

type WelcomeReasonCode =
  | 'TRANSPORT_UNAVAILABLE'
  | 'PEER_DISCONNECTED'
  | 'TIMEOUT'
  | 'INTERNAL_ERROR'
  | 'RETRY_EXHAUSTED';

welcome_send_expired

interface WelcomeSendExpiredEvent {
  type: 'welcome_send_expired';
  peer_id: string;
  message_id: string;
  attempt: number;
  reason_code: WelcomeReasonCode;
}

Group Events

group_created

interface GroupCreatedEvent {
  type: 'group_created';
  group_id: string;
  name: string;
}

group_message_received

interface GroupMessageReceivedEvent {
  type: 'group_message_received';
  group_id: string;
  sender: string;
  content: string;
  timestamp: string;
  message_id: string;
  reply_to_msg?: string;
  forward_info?: ForwardInfo;
}

group_message_sent

interface GroupMessageSentEvent {
  type: 'group_message_sent';
  group_id: string;
  message_ids: string[];
  member_count: number;
}

group_message_partial_failure

interface GroupMessagePartialFailureEvent {
  type: 'group_message_partial_failure';
  group_id: string;
  failed_members: string[];
  succeeded_members: string[];
}

group_member_added

interface GroupMemberAddedEvent {
  type: 'group_member_added';
  group_id: string;
  user_id: string;
  added_by: string;
  group_name?: string;
}

group_member_removed

interface GroupMemberRemovedEvent {
  type: 'group_member_removed';
  group_id: string;
  user_id: string;
  removed_by: string;
}

group_info

interface GroupInfoEvent {
  type: 'group_info';
  group_id: string;
  name: string;
  created_by: string;
  created_at: string;
  members: Array<{
    user_id: string;
    role: string;
    joined_at: string;
  }>;
}

group_role_changed

interface GroupRoleChangedEvent {
  type: 'group_role_changed';
  group_id: string;
  user_id: string;
  new_role: string;
  changed_by: string;
}

group_epoch_fork_detected

Emitted when concurrent MLS commits cause members to diverge. The deterministic leader will attempt automatic resolution.
interface GroupEpochForkDetectedEvent {
  type: 'group_epoch_fork_detected';
  group_id: string;
  local_epoch?: number;
}

group_epoch_fork_resolved

interface GroupEpochForkResolvedEvent {
  type: 'group_epoch_fork_resolved';
  group_id: string;
  resolved_epoch: number;
  failed_members: string[]; // May need re-inviting
}

group_error

interface GroupErrorEvent {
  type: 'group_error';
  reason: string;
}

File Events

file_progress

interface FileProgressEvent {
  type: 'file_progress';
  file_id: string;
  chunks_sent: number;
  total_chunks: number;
  percentage: number;
}

file_received

interface FileReceivedEvent {
  type: 'file_received';
  file_id: string;
  file_name: string;
  file_size: number;
  sender: string;
  content_type: string;
  media_metadata?: {
    mime_type?: string;
    file_name?: string;
    file_size?: number;
    duration_ms?: number;
    width?: number;
    height?: number;
    thumbnail_base64?: string;
  };
  file_data: string;  // Base64-encoded reassembled file
}

media_sent

interface MediaSentEvent {
  type: 'media_sent';
  file_id: string;
  content_type: string;
  recipient: string;
}

Relay Events

relay_promoted

interface RelayPromotedEvent {
  type: 'relay_promoted';
  connection_count: number;
  battery_level: number;
}

relay_demoted

interface RelayDemotedEvent {
  type: 'relay_demoted';
  reason: string;
}

Presence & Typing Events

presence_updated

interface PresenceUpdatedEvent {
  type: 'presence_updated';
  peer_id: string;
  status: 'online' | 'away' | 'offline';
  timestamp: number;
}

typing_indicator_received

interface TypingIndicatorReceivedEvent {
  type: 'typing_indicator_received';
  sender: string;
  conversation_id: string;
  is_typing: boolean;
  timestamp: number;
}

read_receipt_received

interface ReadReceiptReceivedEvent {
  type: 'read_receipt_received';
  sender: string;
  message_ids: string[];
  timestamp: number;
}

Service Discovery Events

service_discovered

interface ServiceDiscoveredEvent {
  type: 'service_discovered';
  query_id: string;
  service_id: string;
  version: string;
  provider_peer_id: string;
  capabilities: Record<string, string>;
  hop_count: number;
}

service_request_received

interface ServiceRequestReceivedEvent {
  type: 'service_request_received';
  request_id: string;
  service_id: string;
  method: string;
  body: string;
  sender: string;
}

service_response_received

interface ServiceResponseReceivedEvent {
  type: 'service_response_received';
  request_id: string;
  service_id: string;
  status: string;
  body: string;
  provider_peer_id: string;
}

DORS Events

dors_score_updated

interface DorsScoreUpdatedEvent {
  type: 'dors_score_updated';
  scores: Array<[string, number]>;  // [transport, score] pairs
}

dors_transport_selected

interface DorsTransportSelectedEvent {
  type: 'dors_transport_selected';
  from: string | null;
  transport: string;
  reason_code: DorsReasonCode;
  score?: number;
}

type DorsReasonCode =
  | 'INITIAL_SELECTION'
  | 'PRIMARY_SELECTED'
  | 'PRIMARY_SUCCESS'
  | 'FALLBACK_SUCCESS'
  | 'ESCALATION_APPLIED'
  | 'CURRENT_UNAVAILABLE';

dors_transport_switched

interface DorsTransportSwitchedEvent {
  type: 'dors_transport_switched';
  from: string | null;
  to: string;
  reason_code: DorsReasonCode;
  reason_detail?: string;
}

dors_escalation_triggered

interface DorsEscalationTriggeredEvent {
  type: 'dors_escalation_triggered';
  phase: 'TRIGGERED' | 'APPLIED';
  from: string;
  to: string;
  reason_code: DorsEscalationReasonCode;
  reason_detail?: string;
}

type DorsEscalationReasonCode =
  | 'FALLBACK_SUCCESS'
  | 'RETRY_THRESHOLD'
  | 'POOR_SIGNAL'
  | 'CONGESTION'
  | 'LOW_TTL'
  | 'LOW_SUCCESS_RATE';

Diagnostic Events

interface DiagnosticEvent {
  type: 'diagnostic';
  level: 'info' | 'warning' | 'error';
  message: string;
  context?: Record<string, unknown>;
}

Next: Types & Internals

Type definitions, DORS scoring, mesh architecture, and troubleshooting.