zerorate-react-native-voip-sdk
v0.1.5
Published
ZeroRate VoIP SDK for React Native
Maintainers
Readme
zerorate-react-native-voip-sdk
[IMPORTANT NOTICE]: This SDK is custom-built for merchants on the freepass.africa platform.
ZeroRate VoIP SDK is a comprehensive React Native library for adding Voice and Video over IP capabilities to your applications. Built on top of LiveKit and WebRTC, it provides a robust, production-ready solution for 1-on-1 calls.
Features
- 📞 Voice & Video Calls: High-quality 1-on-1 audio and video calling.
- 📱 Native Performance: Optimized for mobile using
react-native-webrtc. - 🔔 Call Management: Handles incoming calls, outgoing calls, call acceptance, and rejection.
- 🎨 Built-in UI: Includes customizable, ready-to-use modals for Incoming and Active calls.
- 🔊 Audio Management: Intelligent handling of speakerphone, earpiece, and proximity sensors via
react-native-incall-manager. - 🔌 Event-Driven: comprehensive event system for tracking connection and call states.
Installation
1. Install the SDK
npm install zerorate-react-native-voip-sdk
# or
yarn add zerorate-react-native-voip-sdk2. Install Peer Dependencies
This SDK requires several peer dependencies to function correctly. You must install these in your project:
npm install @livekit/react-native react-native-webrtc react-native-incall-manager react-native-permissions
# or
yarn add @livekit/react-native react-native-webrtc react-native-incall-manager react-native-permissionsPlatform Configuration
Expo (Managed Workflow)
This SDK requires native code and cannot be used with "Expo Go". You must use Development Builds.
Add the Config Plugin: Open your
app.jsonorapp.config.jsand addzerorate-react-native-voip-sdkto thepluginsarray.{ "expo": { "plugins": [ "zerorate-react-native-voip-sdk", [ "expo-camera", { "cameraPermission": "Allow $(PRODUCT_NAME) to access your camera" } ], [ "expo-av", { "microphonePermission": "Allow $(PRODUCT_NAME) to access your microphone" } ], [ "expo-build-properties", { "android": { "minSdkVersion": 24 }, "ios": { "deploymentTarget": "15.1" } } ] ] } }Rebuild Prebuild:
npx expo prebuild --cleanRun Development Build:
npx expo run:android # or npx expo run:ios
Bare React Native
iOS (Info.plist)
Add the following keys to your ios/Runner/Info.plist to request necessary permissions:
<key>NSCameraUsageDescription</key>
<string>We need access to your camera for video calls</string>
<key>NSMicrophoneUsageDescription</key>
<string>We need access to your microphone for audio calls</string>Run pod install in your ios directory after installing dependencies.
Android (AndroidManifest.xml)
Add the following permissions to your android/app/src/main/AndroidManifest.xml:
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />Implementation Guide
1. Initialize the Provider
Wrap your application root (or the section requiring VoIP) with the VoIPProvider. This initializes the SDK and manages the WebSocket connection.
import React from "react";
import { VoIPProvider, VoIPConfig } from "zerorate-react-native-voip-sdk";
import AppContent from "./AppContent";
const voipConfig: VoIPConfig = {
userId: "user-123", // Unique ID for the current user
userName: "John Doe", // Display name
wsUrl: "wss://your-signaling.com", // Your Signaling Server URL
backendUrl: "https://your-api.com", // Your Backend API URL
enableUI: true, // Enable built-in call UI (Recommended)
debug: true, // Enable debug logs for development
};
export default function App() {
return (
<VoIPProvider config={voipConfig}>
<AppContent />
</VoIPProvider>
);
}2. Using the useVoIPContext Hook
Access call methods and state anywhere in your app using the hook.
import React, { useState } from "react";
import { View, Button, Text, TextInput } from "react-native";
import { useVoIPContext } from "zerorate-react-native-voip-sdk";
export default function AppContent() {
const {
isConnected, // Connection status to signaling server
callState, // 'idle' | 'calling' | 'ringing' | 'connected'
initiateCall, // Function to start a call
endCall // Function to hang up
} = useVoIPContext();
const [calleeId, setCalleeId] = useState("");
const handleStartCall = async () => {
if (!calleeId) return;
try {
// initiateCall(calleeUserId, calleeName, options)
await initiateCall(calleeId, "Jane Doe", { isVideo: true });
} catch (err) {
console.error("Failed to start call:", err);
}
};
return (
<View style={{ flex: 1, padding: 20, justifyContent: "center" }}>
<Text>System Status: {isConnected ? "🟢 Online" : "🔴 Offline"}</Text>
{callState === "idle" ? (
<>
<TextInput
placeholder="Enter User ID to call"
value={calleeId}
onChangeText={setCalleeId}
style={{ borderWidth: 1, padding: 10, marginVertical: 10 }}
/>
<Button
title="Start Video Call"
onPress={handleStartCall}
disabled={!isConnected}
/>
</>
) : (
<Button title="End Call" onPress={endCall} color="red" />
)}
</View>
);
}API Reference
VoIPConfig
| Property | Type | Required | Description |
|----------|------|----------|-------------|
| userId | string | Yes | Unique identifier for the local user. |
| userName | string | Yes | Display name for the local user. |
| wsUrl | string | Yes | WebSocket URL for the signaling server. |
| backendUrl | string | Yes | HTTP URL for the backend API. |
| authToken | string | No | Auth token if your backend requires it. |
| enableUI | boolean | No | If true, uses built-in modals. Default: false. |
| theme | 'light' \| 'dark' | No | UI Theme preference. |
| autoReconnect | boolean | No | Reconnect automatically on disconnect. |
| debug | boolean | No | Enable verbose logging. |
useVoIPContext()
Returns an object with:
- State:
isConnected:booleancallState:CallStateactiveCall:CallData | nullincomingCall:CallData | null
- Methods:
initiateCall(userId, userName, options)acceptCall()declineCall()endCall()toggleMicrophone()toggleVideo()switchCamera()
Troubleshooting
❌ "Tried to register two views with the same name RTCVideoView"
This error occurs when you have duplicate copies of react-native-webrtc or @livekit/react-native in your project (e.g., one in your app's node_modules and another nested inside the SDK's node_modules).
Solution:
Ensure that your app's package.json and the SDK both use compatible versions. If you are using a monorepo or local linking, configure your bundler (Metro) to resolve these packages from a single location (usually the app's root).
❌ "PlatformConstants could not be found"
This usually means the native module is not linked.
- Expo: Ensure you added the plugin to
app.jsonand rannpx expo prebuild. Usenpx expo run:androidinstead ofnpx expo start. - Bare RN: Run
pod install(iOS) and rebuild your app.
❌ Audio issues / No sound
The SDK uses react-native-incall-manager. Ensure you have granted microphone permissions. On Android, check that MODIFY_AUDIO_SETTINGS is in your manifest.
License
MIT
