Alaznah

Configure the client and place 1:1 audio calls with Alaznah Calling.

Voice Calls

1:1 audio calls use mediaType: 'audio' (the default when omitted).

Prerequisites: install + peers + native permissions — Quick Start · Permissions.
Tokens: Authentication.

Client config

Wrap your app (or authenticated tree) in CallingProvider before any calling hooks or UI:

tsx
import {
  CallingProvider,
  CallingScreen,
  DEFAULT_HOSTED_SIGNALING_URL,
} from '@alaznah/calling';

const APP_USER_ID = 'alice'; // must match the calling JWT

async function fetchCallingToken(): Promise<string> {
  // Production: call YOUR backend with your app sessionToken
  // Demo: Console Test Token — see Authentication
  const res = await fetch('https://api.yourapp.com/calling/token', {
    headers: { Authorization: `Bearer ${sessionToken}` },
  });
  if (!res.ok) throw new Error('Failed to mint calling token');
  const { token } = await res.json();
  return token;
}

export default function App() {
  return (
    <CallingProvider
      config={{
        userId: APP_USER_ID,
        getAuthToken: fetchCallingToken,
        // Hosted Signaling default — omit, or set explicitly:
        signalingUrl: DEFAULT_HOSTED_SIGNALING_URL, // wss://signal.alaznah.com
      }}
    >
      <CallingScreen userId={APP_USER_ID} defaultPeerId="bob" />
    </CallingProvider>
  );
}
FieldRequiredNotes
userIdYesStable per user; must match token claim
displayNameNoHuman-readable name for default UI; sent as caller name on invite
getAuthTokenYesReturns a short-lived Alaznah calling JWT
signalingUrlNoOmit for Hosted Signaling, or set your WSS URL

Chat apps usually keep their navigator and mount CallingUI as an overlay instead of CallingScreenCall UI.

Permissions

Request the mic before dialing:

ts
import { requestCallPermissions } from '@alaznah/calling';

await requestCallPermissions('audio');

API is 'audio' | 'video' (string). Platform plist / manifest: Permissions.

Start a call

Built-in dialer (inside the provider above):

tsx
<CallingScreen userId={myId} defaultPeerId="bob" />

From your own UI (e.g. chat header) after mounting CallingUI:

ts
const client = useCallingClient();
const ready = useCallingReady();

if (!ready) return;

await requestCallPermissions('audio');
const call = await client.startCall({
  calleeId: 'bob',
  calleeDisplayName: 'Bob', // optional — default UI shows this instead of raw id
  mediaType: 'audio', // optional — audio is the default
});

Accept / decline

Same Incoming Calls flow for voice:

  • Decline — tap the red control
  • Acceptswipe up on the green control (tap does not accept)
ts
await client.accept(callId);
await client.reject(callId, 'declined');

In-call controls

ts
await client.setMuted(true);
await client.setSpeaker(true);
await client.end();
MethodPurpose
setMuted(muted)Mute / unmute local mic
setSpeaker(enabled)Route audio to speaker
end(callId?)Hang up

ActiveCallScreen / CallControls expose these when using CallingScreen or CallingUI.

UI notes (voice)

  • Incoming accept control uses a flipped handset icon inside a green pulse / ripple animation
  • Active voice UI focuses on avatar + audio controls (no local camera preview)