Skip to content

Messaging & calls

The Polkadot app includes end-to-end encrypted chat and one-to-one voice/video calls. Both are built without a dedicated messaging or signaling server: text messages and call-setup signals travel over the same on-chain channel, media attachments are stored on a separate content chain, and the live audio/video stream flows peer-to-peer over WebRTC. This page describes how those pieces fit together and what users or Product developers should expect.

Note

This is the Polkadot Products Devnet, a developer preview. Devnet tokens have no real value and flows may change. See The Polkadot app for how the client tier is structured.

Transport: the statement store

Text messages are neither stored on a server nor sent directly between devices. Each message is end-to-end encrypted and published to the statement store on the People chain. Recipients subscribe to that store and decrypt messages locally.

The same channel carries text, reactions, replies, contact events, and call setup signals. That shared transport is why chat and calls are part of the same product surface.

Encryption

Messages are encrypted per peer, not globally. Only encrypted statements are submitted to the store; the People chain sees ciphertext.

Media attachments: the Bulletin "hop"

Images, video, and files do not go through the statement store. Attachments are encrypted and uploaded through Bulletin-backed storage, while the chat message carries a reference that lets the recipient fetch and decrypt the file. For more on Bulletin storage, see The network.

Voice & video calls

Calls use WebRTC. There is no dedicated signaling server: the offer, answer, connection candidates, and call-close signals are sent as encrypted chat messages over the statement store. Once peers connect, media flows directly when possible, or through TURN when a relay is needed.

NAT traversal (STUN & TURN)

When a direct WebRTC path is not available, clients can use temporary TURN credentials. Those credentials are short-lived and are provided by platform infrastructure, so Product apps should treat calling as a host-mediated service rather than embedding TURN configuration themselves.

Outgoing call flow (Android)

sequenceDiagram
  participant Caller
  participant SS as People chain<br/>statement store
  participant Callee
  Caller->>Caller: Prepare WebRTC session
  Caller->>SS: Send encrypted call offer
  SS-->>Callee: offer statement
  Callee->>SS: Send encrypted answer
  SS-->>Caller: answer statement
  Caller->>SS: Exchange connection candidates
  Callee->>SS: Exchange connection candidates
  Caller-->>Callee: WebRTC media (direct or TURN relay)
  Caller->>SS: End call

Data paths at a glance

flowchart TD
  subgraph ClientA[Client A]
    A1[Chat UI / ChatEngine]
    A2[WebRTC PeerConnection]
  end
  subgraph ClientB[Client B]
    B1[Chat UI / ChatEngine]
    B2[WebRTC PeerConnection]
  end
  SS["People chain statement store"]
  BC["Bulletin-backed attachment storage"]
  TURN["STUN / TURN"]

  A1 -- "E2E-encrypted statements<br/>(text + SDP/ICE call signals)" --> SS
  SS -- subscription --> B1
  A1 -- "chunked AES media" --> BC
  BC -- "fetch by HopTicket" --> B1
  A2 -- "ICE / media (audio+video)" --> TURN
  TURN -- relay --> B2
  A2 -. "direct P2P when possible" .- B2

Desktop specifics and device sync

Desktop chat and device sync use the same broad building blocks, but call initiation is primarily a mobile-app flow in the current Devnet experience.

Common blockers

  • A message appears delayed. The sender and recipient both depend on the statement store subscription and local decryption.
  • An attachment does not open. The encrypted attachment reference may be present before the content is available from Bulletin-backed storage.
  • A call connects only through a relay. That is expected on some networks; TURN credentials are platform-provided and can change.
  • Desktop call behavior differs from mobile. Treat mobile as the primary call surface unless a specific Desktop build documents otherwise.

Learn more