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,
        displayName: 'Alice',
        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
displayNameYesCaller name on invite + native incoming UI
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 CallingScreen — Call 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', // required
  mediaType: 'audio', // optional — audio is the default
});

Accept / decline

Same Incoming Calls flow for voice:

  • Decline — tap the red control
  • Accept — swipe 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)