Files
element-call-Github/sdk
Robin b4bd1f81a0 [SDK] Move SFU authentication into livekit/auth and choose the endpoint by role
The OpenID flow moves to src/livekit/auth/openID.ts with the SFU config
types in a sibling file, takes an options object, and replaces the
MatrixRTC mode with the role we take on the transport plus the session's
slot ID instead of a hard-coded m.call#ROOM.

This changes behaviour: publishers on a livekit_service_url transport
always use the legacy /sfu/get endpoint, so that subscribers can predict
their user:device participant identity, and subscribers always use the
default /get_token endpoint. The MatrixRTC mode no longer influences which
endpoint is used.

On the SDK this lands as sdk/src/media-backend/livekit/auth/ with the connection map, the discriminated connection state and the client-server API flow of the following commits of element-hq/element-call#4331, which rewrite the same files:
- Model ConnectionState as a discriminated union
- Show the whole transport in debug UI and logs (SDK part)
- Let the publishing Connection authenticate itself
- Reduce ConnectionManager to a ConnectionMap
- Use the unstable LiveKit transport type
- Identify transports by server name as well as URLs
- Get SFU tokens and delegate delayed leaves through the MSC4195 CS API
- Fall back to get_token as subscriber on widget API errors
- Share a connection between homeservers using the same JWT service
- Make the auth choice mode independent again

Co-authored-by: Johannes Marbach <n0-0ne+github@mailbox.org>
(cherry picked from commit adb380cd9ed108856e42d992fc03ced8c44f1e56)
2026-10-13 13:00:58 +02:00
..
2026-10-08 13:53:57 +02:00

MatrixRTC SDK (EXPERIMENTAL)

@element-hq/matrixrtc-sdk is the call model under Element Call, on its own: MatrixRTC memberships and transports, media connections, publishing, E2EE keys and the media of every member, as observables. It has no UI. Element Call's own CallViewModel is meant to become one consumer of it. The design is in SdkArchitecture.md, the migration from the view model in SdkMigration.md. Media goes through one media backend behind MediaBackend; LiveKit, under src/media-backend/livekit/, is the only one today and the only place that imports livekit-client.

Status: first implementation. createMatrixRTCClient joins the session, connects to the transport, publishes the local media and exposes every member's media; the development harness and its e2e tests in playwright/sdk drive it, and Element Call's own CallViewModel is built on it. It depends on nothing in Element Call's src/.

Using it

import {
  createMatrixRTCClient,
  E2eeType,
  MatrixRTCMode,
  ObservableScope,
} from "@element-hq/matrixrtc-sdk";

const scope = new ObservableScope();
const rtcClient = createMatrixRTCClient(
  scope,
  client, // a matrix-js-sdk MatrixClient, logged in and syncing
  room, // the matrix-js-sdk Room, from client.getRoom() once the join has synced
  {
    encryptionSystem: { kind: E2eeType.PER_PARTICIPANT },
    matrixRTCMode: MatrixRTCMode.Compatibility,
    publish: [{ source: "microphone" }, { source: "camera" }],
  },
);
rtcClient.join();

rtcClient.remoteMembers$.subscribe((members) => {
  // each member has displayName$, tracks$ and more; a media track is rendered
  // by handing it a <video> or <audio> element: track.attach(element)
});

// later
rtcClient.leave();
scope.end();

dev/main.ts is this example as a working page.

Development

Everything runs from the repository root. This directory is a pnpm project of its own only so that a host can install it as a git dependency (see pnpm-workspace.yaml).

pnpm dev:sdk              # the harness, https://localhost:3002
pnpm build:sdk            # dist/matrixrtc-sdk.js and dist/types
pnpm test:playwright playwright/sdk   # needs `pnpm backend`

Installing

pnpm add github:element-hq/element-call#<ref>&path:/sdk

The host supplies matrix-js-sdk, livekit-client and rxjs; the build leaves them external.