Skip to content

Chat API

Endpoints for peer-to-peer messaging between accounts. Messages are signed with ed25519, stored on the node, and available via polling or real-time Server-Sent Events.

Send Message

POST /chat/send

Sends a message from one account to another.

Request Body

{
  "from": "a1b2c3d4...",
  "to": "e5f6a7b8...",
  "message": "Hello, world!",
  "timestamp": 1709500000000000000,
  "signature": "b8c9d0e1..."
}
Field Type Description
from string Sender's hex-encoded ed25519 public key
to string Recipient's hex-encoded ed25519 public key
message string Message content (plaintext)
timestamp integer Unix nanosecond timestamp
signature string ed25519 signature over the message envelope

Signature

The signature is computed over a length-prefixed binary encoding of the envelope fields:

canonical = [4-byte len][from][4-byte len][to][4-byte len][message][8-byte timestamp BE]
id        = SHA-256(canonical)
signature = ed25519.Sign(sender_private_key, id)

The length-prefixed encoding prevents field boundary collisions. This proves the sender controls the from account's private key and that the message has not been tampered with.

Response

{
  "ok": true
}

Errors

Status Description
400 Invalid message (bad signature, missing fields)

Message storage

Messages are stored on the recipient's node. The maximum number of messages retained per account is configurable. Older messages are pruned when the limit is exceeded.

Example

curl -X POST http://localhost:8080/chat/send \
  -H "Content-Type: application/json" \
  -d '{
    "from": "a1b2c3d4...",
    "to": "e5f6a7b8...",
    "message": "Hello, world!",
    "timestamp": 1709500000000000000,
    "signature": "b8c9d0e1..."
  }'

Get Messages

GET /chat/messages

Retrieves messages for an account, optionally filtered by timestamp.

Query Parameters

Parameter Type Required Description
account string Yes Hex-encoded public key to fetch messages for
since integer No Only return messages after this unix nanosecond timestamp

Response

[
  {
    "from": "e5f6a7b8...",
    "to": "a1b2c3d4...",
    "message": "Hey there!",
    "timestamp": 1709500060000000000,
    "signature": "d5e6f7a8..."
  },
  {
    "from": "a1b2c3d4...",
    "to": "e5f6a7b8...",
    "message": "Hello, world!",
    "timestamp": 1709500000000000000,
    "signature": "b8c9d0e1..."
  }
]

Messages are returned in reverse chronological order (newest first). Both sent and received messages for the account are included.

Example

# All messages for an account
curl "http://localhost:8080/chat/messages?account=a1b2c3d4..."

# Messages since a specific time
curl "http://localhost:8080/chat/messages?account=a1b2c3d4...&since=1709500000000000000"

List Contacts

GET /chat/contacts

Returns a list of accounts that have exchanged messages with the node's accounts.

Response

[
  "a1b2c3d4...",
  "e5f6a7b8...",
  "c9d0e1f2..."
]

Returns an array of hex-encoded account addresses.

Example

curl http://localhost:8080/chat/contacts

Real-Time Message Stream

GET /chat/events

Opens a Server-Sent Events (SSE) connection for real-time message delivery.

Query Parameters

Parameter Type Required Description
account string No Filter events to messages involving this account

Event Format

event: message
data: {"from":"e5f6a7b8...","to":"a1b2c3d4...","message":"New message!","timestamp":1709500120000000000,"signature":"f3a4b5c6..."}

Each event has:

  • event type: message
  • data: JSON-encoded message envelope

Connection

# All messages
curl -N http://localhost:8080/chat/events

# Messages for a specific account
curl -N "http://localhost:8080/chat/events?account=a1b2c3d4..."

SSE reconnection

SSE clients automatically reconnect on disconnect. The since parameter on the polling endpoint can be used to backfill any messages missed during disconnection.

JavaScript Example

const source = new EventSource('/chat/events?account=a1b2c3d4...');

source.addEventListener('message', (event) => {
  const msg = JSON.parse(event.data);
  console.log(`${msg.from}: ${msg.message}`);
});

Message Envelope

All messages use the same envelope structure:

Field Type Description
from string Sender's hex-encoded ed25519 public key
to string Recipient's hex-encoded ed25519 public key
message string Message content
timestamp integer Unix nanosecond timestamp
signature string ed25519 signature proving sender authenticity