production
wss://messagebox.babbage.systems/
Production MessageBox WebSocket endpoint (Socket.IO over WSS).
- host
messagebox.babbage.systems- pathname
/- protocol
wss- description
Production MessageBox WebSocket endpoint (Socket.IO over WSS).
wss://messagebox.babbage.systems/
messagebox.babbage.systems/wssProduction MessageBox WebSocket endpoint (Socket.IO over WSS).ws://localhost:{port}/
localhost:{port}/wsLocal development Socket.IO server.5001HTTP port the MessageBox Server listens on.authMessage
authMessageLow-level Socket.IO event used by `SocketServerTransport` to carry
BRC-103 `AuthMessage` frames. This event is NOT an application event;
it is emitted and received transparently by the `Peer` class from
`@bsv/sdk`. Application developers do not interact with this channel
directly — they use the typed events below.
See `packages/messaging/authsocket/src/SocketServerTransport.ts`.
authMessageFrameBRC-103 auth frame (both directions — client and server).#/components/schemas/AuthMessageauthenticated
authenticatedFallback authentication event. The client emits this when its identity
key was not included in the Socket.IO handshake. The server validates
the key, updates its in-memory `authenticatedSockets` map, and emits
`authenticationSuccess` or `authenticationFailed` in response.
authenticateMessageClient sends its identity key for post-connection auth.#/components/schemas/AuthenticatePayloadauthenticationSuccess
authenticationSuccessEmitted by the server after successful identity key validation.authSuccessMessage#/components/schemas/AuthSuccessPayloadauthenticationFailed
authenticationFailedEmitted by the server when identity key validation fails.authFailedMessage#/components/schemas/AuthFailedPayloadjoinRoom
joinRoomClient requests to subscribe to a room. Only authenticated sockets may
join rooms. The server responds with `joinedRoom` on success or
`joinFailed` on error.
Room ID convention: `<recipientIdentityKey>-<messageBoxType>`.
joinRoomMessageRoom ID string to join.#/components/schemas/JoinRoomPayloadjoinedRoom
joinedRoomServer confirms the client has joined the specified room.joinedRoomMessage#/components/schemas/JoinedRoomPayloadjoinFailed
joinFailedEmitted when `joinRoom` fails (unauthenticated or invalid roomId).joinFailedMessage#/components/schemas/JoinFailedPayloadleaveRoom
leaveRoomClient requests to leave a room.leaveRoomMessageRoom ID string to leave.#/components/schemas/LeaveRoomPayloadleftRoom
leftRoomServer confirms the client has left the room.leftRoomMessage#/components/schemas/LeftRoomPayloadleaveFailed
leaveFailedEmitted when `leaveRoom` fails.leaveFailedMessage#/components/schemas/LeaveFailedPayloadsendMessage
sendMessageClient sends a message to a recipient via WebSocket when operator
monetization is disabled. Paid servers return an error acknowledgement
that instructs current clients to use their AuthFetch HTTP fallback. The
unpriced WebSocket path:
1. Validates the sender is authenticated.
2. Validates `roomId` and `message`.
3. Creates the message box if it does not exist.
4. Inserts the message into the database (with ON CONFLICT IGNORE dedup).
5. Emits `sendMessageAck-{roomId}` back to the sender.
6. Broadcasts `sendMessage-{roomId}` to all connections in the room.
sendMessageMessage#/components/schemas/WsSendMessagePayloadsendMessageAck-{roomId}
sendMessageAck-{roomId}Per-room acknowledgement emitted to the sender after the message is
stored or when the request must fall back to AuthFetch. The event name is
`sendMessageAck-<roomId>` where `roomId` matches the value in the
originating `sendMessage` payload.
The room ID from the originating sendMessage request.sendMessageAckMessage#/components/schemas/WsSendMessageAckPayloadsendMessage-{roomId}
sendMessage-{roomId}Broadcast emitted to all connections subscribed to `roomId` after a
successful `sendMessage`. The event name is `sendMessage-<roomId>`.
The target room ID.sendMessageBroadcastMessage#/components/schemas/WsSendMessageBroadcastPayloadmessageFailed
messageFailedEmitted to the sender when `sendMessage` processing fails.messageFailedMessage#/components/schemas/MessageFailedPayloadpaymentFailed
paymentFailedEmitted to unauthenticated sockets that attempt to send a message
(same event name reused from older payment-gate logic).
paymentFailedMessage#/components/schemas/PaymentFailedPayloaddisconnect
disconnectStandard Socket.IO disconnect event. The server removes the socket from
the `authenticatedSockets` map and the `peers` map in `AuthSocketServer`.
disconnectMessage#/components/schemas/DisconnectPayloadreceive#/channels/authMessageServer receives an AuthMessage frame from the client during BRC-103 handshake.#/channels/authMessage/messages/authMessageFramesend#/channels/authMessageServer sends an AuthMessage frame to the client during BRC-103 handshake.#/channels/authMessage/messages/authMessageFramereceive#/channels/authenticatedServer receives the client's identity key on the 'authenticated' event.#/channels/authenticated/messages/authenticateMessagesend#/channels/authenticationSuccessServer confirms successful identity key validation.#/channels/authenticationSuccess/messages/authSuccessMessagesend#/channels/authenticationFailedServer rejects an invalid identity key.#/channels/authenticationFailed/messages/authFailedMessagereceive#/channels/joinRoomServer receives a room join request.#/channels/joinRoom/messages/joinRoomMessagesend#/channels/joinedRoomServer confirms room join.#/channels/joinedRoom/messages/joinedRoomMessagesend#/channels/joinFailedServer signals room join failure.#/channels/joinFailed/messages/joinFailedMessagereceive#/channels/leaveRoomServer receives a room leave request.#/channels/leaveRoom/messages/leaveRoomMessagesend#/channels/leftRoomServer confirms room leave.#/channels/leftRoom/messages/leftRoomMessagesend#/channels/leaveFailedServer signals room leave failure.#/channels/leaveFailed/messages/leaveFailedMessagereceive#/channels/sendMessageServer receives a message from the client to deliver to a recipient.#/channels/sendMessage/messages/sendMessageMessagesend#/channels/sendMessageAckServer acknowledges delivery of a message to the sender.#/channels/sendMessageAck/messages/sendMessageAckMessagesend#/channels/sendMessageBroadcastServer broadcasts a new message to all room subscribers.#/channels/sendMessageBroadcast/messages/sendMessageBroadcastMessagesend#/channels/messageFailedServer signals message delivery failure.#/channels/messageFailed/messages/messageFailedMessagesend#/channels/paymentFailedServer signals auth/payment gate rejection.#/channels/paymentFailed/messages/paymentFailedMessagereceive#/channels/disconnectClient disconnects; server cleans up in-memory state.#/channels/disconnect/messages/disconnectMessagestring^0[23][0-9a-fA-F]{64}$Compressed secp256k1 public key, 66 hex characters.objectBRC-103 auth envelope as defined in `@bsv/sdk`. Carried on the
low-level `authMessage` Socket.IO event. Not an application-level event.
messageTypeversionidentityKeystringinitialRequestinitialResponsegeneral- `initialRequest` — first handshake message from initiating peer
- `initialResponse` — server's challenge response (includes nonce, signature)
- `general` — signed application payload after handshake
stringAuth protocol version string.#/components/schemas/PubKeyHexstringFresh random nonce (base64) generated by the sender.stringEcho of the peer's nonce from the previous message.stringPresent in `initialRequest`; absent in subsequent messages.arrayintegerSigned application payload (byte array). Empty for handshake messages.arrayintegerDER-encoded ECDSA signature over the payload.objectOptional certificate request set (BRC-52 format).trueobjectApplication-level wrapper JSON-encoded inside the BRC-103 `general`
message payload. The `SocketServerTransport` encodes/decodes this
transparently; application code only sees `eventName` and `data`.
eventNamedatastringThe Socket.IO event name.The event-specific payload.objectSent by the client on the `authenticated` event when the identity key
was not available at connection time (fallback path). The server validates
the key and responds with `authenticationSuccess` or `authenticationFailed`.
#/components/schemas/PubKeyHexobjectstatusstringsuccessobjectreasonstringHuman-readable reason for failure.stringThe room ID string sent by the client on the `joinRoom` event.
Room IDs use the convention `<recipientKey>-<messageBoxType>`.
Example: `028d37b9...-payment_inbox`.
objectroomIdstringobjectreasonstringstringThe room ID string sent by the client on the `leaveRoom` event.objectroomIdstringobjectreasonstringobjectPayload for the client-to-server `sendMessage` event.roomIdmessagestringTarget room. Format: `<recipientKey>-<messageBoxType>`.
The server removes the exact recipient-key prefix and uses the
authenticated sender key from `authenticatedSockets`.
objectmessageIdrecipientbodystringUnique identifier for this message (deduplication key).#/components/schemas/PubKeyHexstringMessage body string.objectAcknowledgement emitted by the server on `sendMessageAck-{roomId}`. A
successful write includes `messageId`. An error includes `code`; paid
servers use `ERR_PAYMENT_REQUIRES_AUTHFETCH` so compatible clients retry
the send through the BRC-105 AuthFetch HTTP path.
statusstringsuccesserrorstringstringobjectBroadcast emitted by the server on `sendMessage-{roomId}` to all
connections in the room (including the sender). Note: the event name
is dynamic.
sendermessageIdbody#/components/schemas/PubKeyHexstringstringobjectreasonstringobjectreasonstringstringThe Socket.IO disconnect reason string (e.g. `transport close`,
`server namespace disconnect`).
asyncapi: "3.1.0"
info:
title: AuthSocket WebSocket Protocol
version: "1.0.0"
description: |
AsyncAPI 3.0 specification for the `AuthSocketServer` / `AuthSocket`
WebSocket channel used by the BSV MessageBox Server.
## Transport layer
`AuthSocketServer` wraps Socket.IO and sits on top of an HTTP server.
All Socket.IO events are standard Socket.IO framing; this spec describes
the *application-level* event names and payload shapes that flow over the
Socket.IO connection.
## BRC-103 mutual authentication
Every Socket.IO connection undergoes BRC-103 (`Peer`) handshake before
application events are exchanged. The handshake is carried on the
**`authMessage`** event using the `AuthMessage` envelope defined in the
`@bsv/sdk` `Transport` interface.
Once the handshake succeeds the peer's `identityKey` (compressed secp256k1
public key, 66-char hex) is known server-side and stored in memory for the
lifetime of the connection.
## Application events
After authentication the server emits and listens for the events described
below. All application payloads are serialized as JSON inside the
BRC-103 `general` message (`Peer.toPeer`). The transport layer
(`SocketServerTransport`) wraps them in an `{ eventName, data }` envelope
before signing.
Source of truth:
- `packages/messaging/authsocket/src/AuthSocketServer.ts`
- `packages/messaging/authsocket/src/SocketServerTransport.ts`
- `packages/messaging/message-box-server/src/index.ts`
servers:
production:
host: "messagebox.babbage.systems"
pathname: "/"
protocol: wss
description: Production MessageBox WebSocket endpoint (Socket.IO over WSS).
local:
host: "localhost:{port}"
pathname: "/"
protocol: ws
description: Local development Socket.IO server.
variables:
port:
default: "5001"
description: HTTP port the MessageBox Server listens on.
# ---------------------------------------------------------------------------
# Components
# ---------------------------------------------------------------------------
components:
schemas:
PubKeyHex:
type: string
pattern: "^0[23][0-9a-fA-F]{64}$"
description: Compressed secp256k1 public key, 66 hex characters.
AuthMessage:
type: object
description: |
BRC-103 auth envelope as defined in `@bsv/sdk`. Carried on the
low-level `authMessage` Socket.IO event. Not an application-level event.
required: [messageType, version, identityKey]
properties:
messageType:
type: string
enum: [initialRequest, initialResponse, general]
description: |
- `initialRequest` — first handshake message from initiating peer
- `initialResponse` — server's challenge response (includes nonce, signature)
- `general` — signed application payload after handshake
version:
type: string
description: Auth protocol version string.
identityKey:
$ref: "#/components/schemas/PubKeyHex"
nonce:
type: string
description: Fresh random nonce (base64) generated by the sender.
yourNonce:
type: string
description: Echo of the peer's nonce from the previous message.
initialNonce:
type: string
description: Present in `initialRequest`; absent in subsequent messages.
payload:
type: array
items:
type: integer
description: Signed application payload (byte array). Empty for handshake messages.
signature:
type: array
items:
type: integer
description: DER-encoded ECDSA signature over the payload.
requestedCertificates:
type: object
description: Optional certificate request set (BRC-52 format).
additionalProperties: true
EventEnvelope:
type: object
description: |
Application-level wrapper JSON-encoded inside the BRC-103 `general`
message payload. The `SocketServerTransport` encodes/decodes this
transparently; application code only sees `eventName` and `data`.
required: [eventName, data]
properties:
eventName:
type: string
description: The Socket.IO event name.
data:
description: The event-specific payload.
# ----- Authentication flow -----
AuthenticatePayload:
type: object
description: |
Sent by the client on the `authenticated` event when the identity key
was not available at connection time (fallback path). The server validates
the key and responds with `authenticationSuccess` or `authenticationFailed`.
properties:
identityKey:
$ref: "#/components/schemas/PubKeyHex"
AuthSuccessPayload:
type: object
required: [status]
properties:
status:
type: string
enum: [success]
AuthFailedPayload:
type: object
required: [reason]
properties:
reason:
type: string
description: Human-readable reason for failure.
# ----- Room management -----
JoinRoomPayload:
type: string
description: |
The room ID string sent by the client on the `joinRoom` event.
Room IDs use the convention `<recipientKey>-<messageBoxType>`.
Example: `028d37b9...-payment_inbox`.
JoinedRoomPayload:
type: object
required: [roomId]
properties:
roomId:
type: string
JoinFailedPayload:
type: object
required: [reason]
properties:
reason:
type: string
LeaveRoomPayload:
type: string
description: The room ID string sent by the client on the `leaveRoom` event.
LeftRoomPayload:
type: object
required: [roomId]
properties:
roomId:
type: string
LeaveFailedPayload:
type: object
required: [reason]
properties:
reason:
type: string
# ----- Message sending -----
WsSendMessagePayload:
type: object
description: Payload for the client-to-server `sendMessage` event.
required: [roomId, message]
properties:
roomId:
type: string
description: |
Target room. Format: `<recipientKey>-<messageBoxType>`.
The server removes the exact recipient-key prefix and uses the
authenticated sender key from `authenticatedSockets`.
message:
type: object
required: [messageId, recipient, body]
properties:
messageId:
type: string
description: Unique identifier for this message (deduplication key).
recipient:
$ref: "#/components/schemas/PubKeyHex"
body:
type: string
description: Message body string.
WsSendMessageAckPayload:
type: object
description: |
Acknowledgement emitted by the server on `sendMessageAck-{roomId}`. A
successful write includes `messageId`. An error includes `code`; paid
servers use `ERR_PAYMENT_REQUIRES_AUTHFETCH` so compatible clients retry
the send through the BRC-105 AuthFetch HTTP path.
required: [status]
properties:
status:
type: string
enum: [success, error]
messageId:
type: string
code:
type: string
WsSendMessageBroadcastPayload:
type: object
description: |
Broadcast emitted by the server on `sendMessage-{roomId}` to all
connections in the room (including the sender). Note: the event name
is dynamic.
required: [sender, messageId, body]
properties:
sender:
$ref: "#/components/schemas/PubKeyHex"
messageId:
type: string
body:
type: string
MessageFailedPayload:
type: object
required: [reason]
properties:
reason:
type: string
PaymentFailedPayload:
type: object
required: [reason]
properties:
reason:
type: string
DisconnectPayload:
type: string
description: |
The Socket.IO disconnect reason string (e.g. `transport close`,
`server namespace disconnect`).
# ---------------------------------------------------------------------------
# Channels
# ---------------------------------------------------------------------------
channels:
# -------- Low-level auth handshake (BRC-103 / Peer transport) --------
authMessage:
address: authMessage
description: |
Low-level Socket.IO event used by `SocketServerTransport` to carry
BRC-103 `AuthMessage` frames. This event is NOT an application event;
it is emitted and received transparently by the `Peer` class from
`@bsv/sdk`. Application developers do not interact with this channel
directly — they use the typed events below.
See `packages/messaging/authsocket/src/SocketServerTransport.ts`.
messages:
authMessageFrame:
name: authMessageFrame
summary: BRC-103 auth frame (both directions — client and server).
payload:
$ref: "#/components/schemas/AuthMessage"
# -------- Application authentication --------
authenticated:
address: authenticated
description: |
Fallback authentication event. The client emits this when its identity
key was not included in the Socket.IO handshake. The server validates
the key, updates its in-memory `authenticatedSockets` map, and emits
`authenticationSuccess` or `authenticationFailed` in response.
messages:
authenticateMessage:
name: authenticateMessage
summary: Client sends its identity key for post-connection auth.
payload:
$ref: "#/components/schemas/AuthenticatePayload"
authenticationSuccess:
address: authenticationSuccess
description: Emitted by the server after successful identity key validation.
messages:
authSuccessMessage:
name: authSuccessMessage
payload:
$ref: "#/components/schemas/AuthSuccessPayload"
authenticationFailed:
address: authenticationFailed
description: Emitted by the server when identity key validation fails.
messages:
authFailedMessage:
name: authFailedMessage
payload:
$ref: "#/components/schemas/AuthFailedPayload"
# -------- Room management --------
joinRoom:
address: joinRoom
description: |
Client requests to subscribe to a room. Only authenticated sockets may
join rooms. The server responds with `joinedRoom` on success or
`joinFailed` on error.
Room ID convention: `<recipientIdentityKey>-<messageBoxType>`.
messages:
joinRoomMessage:
name: joinRoomMessage
summary: Room ID string to join.
payload:
$ref: "#/components/schemas/JoinRoomPayload"
joinedRoom:
address: joinedRoom
description: Server confirms the client has joined the specified room.
messages:
joinedRoomMessage:
name: joinedRoomMessage
payload:
$ref: "#/components/schemas/JoinedRoomPayload"
joinFailed:
address: joinFailed
description: Emitted when `joinRoom` fails (unauthenticated or invalid roomId).
messages:
joinFailedMessage:
name: joinFailedMessage
payload:
$ref: "#/components/schemas/JoinFailedPayload"
leaveRoom:
address: leaveRoom
description: Client requests to leave a room.
messages:
leaveRoomMessage:
name: leaveRoomMessage
summary: Room ID string to leave.
payload:
$ref: "#/components/schemas/LeaveRoomPayload"
leftRoom:
address: leftRoom
description: Server confirms the client has left the room.
messages:
leftRoomMessage:
name: leftRoomMessage
payload:
$ref: "#/components/schemas/LeftRoomPayload"
leaveFailed:
address: leaveFailed
description: Emitted when `leaveRoom` fails.
messages:
leaveFailedMessage:
name: leaveFailedMessage
payload:
$ref: "#/components/schemas/LeaveFailedPayload"
# -------- Message sending --------
sendMessage:
address: sendMessage
description: |
Client sends a message to a recipient via WebSocket when operator
monetization is disabled. Paid servers return an error acknowledgement
that instructs current clients to use their AuthFetch HTTP fallback. The
unpriced WebSocket path:
1. Validates the sender is authenticated.
2. Validates `roomId` and `message`.
3. Creates the message box if it does not exist.
4. Inserts the message into the database (with ON CONFLICT IGNORE dedup).
5. Emits `sendMessageAck-{roomId}` back to the sender.
6. Broadcasts `sendMessage-{roomId}` to all connections in the room.
messages:
sendMessageMessage:
name: sendMessageMessage
payload:
$ref: "#/components/schemas/WsSendMessagePayload"
sendMessageAck:
address: "sendMessageAck-{roomId}"
description: |
Per-room acknowledgement emitted to the sender after the message is
stored or when the request must fall back to AuthFetch. The event name is
`sendMessageAck-<roomId>` where `roomId` matches the value in the
originating `sendMessage` payload.
parameters:
roomId:
description: The room ID from the originating sendMessage request.
messages:
sendMessageAckMessage:
name: sendMessageAckMessage
payload:
$ref: "#/components/schemas/WsSendMessageAckPayload"
sendMessageBroadcast:
address: "sendMessage-{roomId}"
description: |
Broadcast emitted to all connections subscribed to `roomId` after a
successful `sendMessage`. The event name is `sendMessage-<roomId>`.
parameters:
roomId:
description: The target room ID.
messages:
sendMessageBroadcastMessage:
name: sendMessageBroadcastMessage
payload:
$ref: "#/components/schemas/WsSendMessageBroadcastPayload"
messageFailed:
address: messageFailed
description: Emitted to the sender when `sendMessage` processing fails.
messages:
messageFailedMessage:
name: messageFailedMessage
payload:
$ref: "#/components/schemas/MessageFailedPayload"
paymentFailed:
address: paymentFailed
description: |
Emitted to unauthenticated sockets that attempt to send a message
(same event name reused from older payment-gate logic).
messages:
paymentFailedMessage:
name: paymentFailedMessage
payload:
$ref: "#/components/schemas/PaymentFailedPayload"
# -------- Lifecycle --------
disconnect:
address: disconnect
description: |
Standard Socket.IO disconnect event. The server removes the socket from
the `authenticatedSockets` map and the `peers` map in `AuthSocketServer`.
messages:
disconnectMessage:
name: disconnectMessage
payload:
$ref: "#/components/schemas/DisconnectPayload"
# ---------------------------------------------------------------------------
# Operations
# ---------------------------------------------------------------------------
operations:
# --- Auth handshake (transport-level, both directions) ---
receiveAuthMessage:
action: receive
channel:
$ref: "#/channels/authMessage"
summary: Server receives an AuthMessage frame from the client during BRC-103 handshake.
messages:
- $ref: "#/channels/authMessage/messages/authMessageFrame"
sendAuthMessage:
action: send
channel:
$ref: "#/channels/authMessage"
summary: Server sends an AuthMessage frame to the client during BRC-103 handshake.
messages:
- $ref: "#/channels/authMessage/messages/authMessageFrame"
# --- Client authentication ---
receiveAuthenticated:
action: receive
channel:
$ref: "#/channels/authenticated"
summary: Server receives the client's identity key on the 'authenticated' event.
messages:
- $ref: "#/channels/authenticated/messages/authenticateMessage"
sendAuthenticationSuccess:
action: send
channel:
$ref: "#/channels/authenticationSuccess"
summary: Server confirms successful identity key validation.
messages:
- $ref: "#/channels/authenticationSuccess/messages/authSuccessMessage"
sendAuthenticationFailed:
action: send
channel:
$ref: "#/channels/authenticationFailed"
summary: Server rejects an invalid identity key.
messages:
- $ref: "#/channels/authenticationFailed/messages/authFailedMessage"
# --- Room management ---
receiveJoinRoom:
action: receive
channel:
$ref: "#/channels/joinRoom"
summary: Server receives a room join request.
messages:
- $ref: "#/channels/joinRoom/messages/joinRoomMessage"
sendJoinedRoom:
action: send
channel:
$ref: "#/channels/joinedRoom"
summary: Server confirms room join.
messages:
- $ref: "#/channels/joinedRoom/messages/joinedRoomMessage"
sendJoinFailed:
action: send
channel:
$ref: "#/channels/joinFailed"
summary: Server signals room join failure.
messages:
- $ref: "#/channels/joinFailed/messages/joinFailedMessage"
receiveLeaveRoom:
action: receive
channel:
$ref: "#/channels/leaveRoom"
summary: Server receives a room leave request.
messages:
- $ref: "#/channels/leaveRoom/messages/leaveRoomMessage"
sendLeftRoom:
action: send
channel:
$ref: "#/channels/leftRoom"
summary: Server confirms room leave.
messages:
- $ref: "#/channels/leftRoom/messages/leftRoomMessage"
sendLeaveFailed:
action: send
channel:
$ref: "#/channels/leaveFailed"
summary: Server signals room leave failure.
messages:
- $ref: "#/channels/leaveFailed/messages/leaveFailedMessage"
# --- Message sending ---
receiveSendMessage:
action: receive
channel:
$ref: "#/channels/sendMessage"
summary: Server receives a message from the client to deliver to a recipient.
messages:
- $ref: "#/channels/sendMessage/messages/sendMessageMessage"
sendSendMessageAck:
action: send
channel:
$ref: "#/channels/sendMessageAck"
summary: Server acknowledges delivery of a message to the sender.
messages:
- $ref: "#/channels/sendMessageAck/messages/sendMessageAckMessage"
sendSendMessageBroadcast:
action: send
channel:
$ref: "#/channels/sendMessageBroadcast"
summary: Server broadcasts a new message to all room subscribers.
messages:
- $ref: "#/channels/sendMessageBroadcast/messages/sendMessageBroadcastMessage"
sendMessageFailed:
action: send
channel:
$ref: "#/channels/messageFailed"
summary: Server signals message delivery failure.
messages:
- $ref: "#/channels/messageFailed/messages/messageFailedMessage"
sendPaymentFailed:
action: send
channel:
$ref: "#/channels/paymentFailed"
summary: Server signals auth/payment gate rejection.
messages:
- $ref: "#/channels/paymentFailed/messages/paymentFailedMessage"
# --- Lifecycle ---
receiveDisconnect:
action: receive
channel:
$ref: "#/channels/disconnect"
summary: Client disconnects; server cleans up in-memory state.
messages:
- $ref: "#/channels/disconnect/messages/disconnectMessage"