@dora-cell/sdk 0.1.1-beta.26 → 0.1.1-beta.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -8,9 +8,9 @@ VoIP calling SDK for Dora Cell - Make calls from any JavaScript application with
8
8
  ✅ **TypeScript support** - Full type definitions included
9
9
  ✅ **WebRTC-based** - High-quality voice calls using JsSIP
10
10
  ✅ **Event-driven API** - Listen to call state changes
11
- ✅ **API token authentication** - Secure, no user login required
11
+ ✅ **Multiple Auth Modes** - Support for API Token and Direct Extension login
12
12
  ✅ **Auto-extension selection** - Automatically selects first available extension
13
- ✅ **React bindings** - Optional React hooks for easy integration
13
+ ✅ **React bindings** - Optional React hooks for easy integration
14
14
 
15
15
  ## Installation
16
16
 
@@ -22,110 +22,68 @@ yarn add @dora-cell/sdk jssip
22
22
  pnpm add @dora-cell/sdk jssip
23
23
  ```
24
24
 
25
- For React projects:
26
- ```bash
27
- npm install @dora-cell/sdk @dora-cell/sdk-react jssip
28
- ```
29
-
30
25
  ## Quick Start
31
26
 
32
- ### Vanilla JavaScript
27
+ ### 1. Initialize the SDK
28
+
29
+ Choose your preferred authentication method:
30
+
31
+ #### Option A: Extension Authentication (Recommended for Testing)
32
+
33
+ Best for quick testing or internal apps where default credentials are used.
33
34
 
34
35
  ```javascript
35
- import { DoraCell } from '@dora-cell/sdk';
36
+ import { DoraCell } from "@dora-cell/sdk";
36
37
 
37
- // Initialize SDK with API token
38
38
  const sdk = new DoraCell({
39
39
  auth: {
40
- type: 'api-token',
41
- apiToken: 'your-api-token-here',
42
- apiBaseUrl: 'https://api.usedora.com'
40
+ type: "extension",
41
+ extension: "1001",
43
42
  },
44
- debug: true // Enable console logging
45
43
  });
44
+ ```
46
45
 
47
- // Initialize connection
48
- await sdk.initialize();
46
+ #### Option B: API Token Authentication (Production)
49
47
 
50
- // Listen for connection status
51
- sdk.on('connection:status', (state) => {
52
- console.log('Connection status:', state.status);
53
- });
48
+ Securely fetch credentials from your backend.
54
49
 
55
- // Listen for call events
56
- sdk.on('call:connected', (call) => {
57
- console.log('Call connected:', call.remoteNumber);
50
+ ```javascript
51
+ const sdk = new DoraCell({
52
+ auth: {
53
+ type: "api-token",
54
+ apiToken: "your-api-token-here",
55
+ apiBaseUrl: "https://api.yourdomain.com",
56
+ },
58
57
  });
58
+ ```
59
+
60
+ ### 2. Connect and Register
59
61
 
60
- sdk.on('call:ended', (call, reason) => {
61
- console.log('Call ended:', reason);
62
+ ```javascript
63
+ // Listen for registration
64
+ sdk.on("connection:status", (state) => {
65
+ if (state.status === "registered") {
66
+ console.log("SIP Ready to make calls!");
67
+ }
62
68
  });
63
69
 
64
- // Make a call
65
- const call = await sdk.call('+2348012345678');
70
+ // Initialize connection
71
+ await sdk.initialize();
72
+ ```
66
73
 
67
- // Mute/unmute
68
- call.mute();
69
- call.unmute();
74
+ ### 3. Make a Call
70
75
 
71
- // Hang up
72
- call.hangup();
73
- ```
76
+ ```javascript
77
+ try {
78
+ const call = await sdk.call("+2348012345678");
74
79
 
75
- ### React
76
-
77
- ```tsx
78
- import { DoraCellProvider, useCall, useConnectionStatus } from '@dora-cell/sdk-react';
79
-
80
- function App() {
81
- return (
82
- <DoraCellProvider
83
- config={{
84
- auth: {
85
- type: 'api-token',
86
- apiToken: 'your-api-token-here',
87
- apiBaseUrl: 'https://api.usedora.com'
88
- }
89
- }}
90
- >
91
- <CallInterface />
92
- </DoraCellProvider>
93
- );
94
- }
80
+ // Mute/unmute
81
+ call.mute();
95
82
 
96
- function CallInterface() {
97
- const { call, hangup, toggleMute, callStatus, callDuration, isMuted } = useCall();
98
- const { isConnected } = useConnectionStatus();
99
- const [number, setNumber] = useState('');
100
-
101
- const handleCall = async () => {
102
- try {
103
- await call(number);
104
- } catch (error) {
105
- console.error('Call failed:', error);
106
- }
107
- };
108
-
109
- return (
110
- <div>
111
- <p>Status: {isConnected ? 'Connected' : 'Disconnected'}</p>
112
- <input
113
- value={number}
114
- onChange={(e) => setNumber(e.target.value)}
115
- placeholder="Enter phone number"
116
- />
117
- <button onClick={handleCall} disabled={!isConnected}>
118
- Call
119
- </button>
120
- {callStatus === 'ongoing' && (
121
- <>
122
- <p>Duration: {callDuration}</p>
123
- <button onClick={toggleMute}>{isMuted ? 'Unmute' : 'Mute'}</button>
124
- <button onClick={hangup}>Hang Up</button>
125
- </>
126
- )}
127
- </div>
128
- );
83
+ // Hang up
84
+ call.hangup();
85
+ } catch (error) {
86
+ console.error("Call failed:", error.message);
129
87
  }
130
88
  ```
131
89
 
@@ -133,143 +91,39 @@ function CallInterface() {
133
91
 
134
92
  ### DoraCell Class
135
93
 
136
- #### Constructor
137
-
138
- ```typescript
139
- new DoraCell(config: DoraCellConfig)
140
- ```
94
+ #### `new DoraCell(config)`
141
95
 
142
- **Config options:**
143
- - `auth` - Authentication configuration (required)
144
- - `type: 'api-token'` - Use API token authentication
145
- - `apiToken: string` - Your Dora Cell API token
146
- - `apiBaseUrl?: string` - API base URL (optional)
147
- - `turnServers?: RTCIceServer[]` - Custom TURN/STUN servers
148
- - `debug?: boolean` - Enable debug logging
149
- - `autoSelectExtension?: boolean` - Auto-select first extension (default: true)
96
+ - `config.auth` (Required)
97
+ - `type: 'extension' | 'api-token'`
98
+ - `extension: string` (for extension type)
99
+ - `apiToken: string` (for api-token type)
100
+ - `config.debug?: boolean` - Enable JsSIP debug logs (default: false)
150
101
 
151
102
  #### Methods
152
103
 
153
- **`initialize(): Promise<void>`**
154
- Initialize the SDK and connect to SIP server.
155
-
156
- **`call(phoneNumber: string, options?: CallOptions): Promise<Call>`**
157
- Make an outbound call.
158
-
159
- Options:
160
- - `extension?: string` - Specific extension to use for this call
161
-
162
- **`hangup(): void`**
163
- Hang up the current call.
164
-
165
- **`answerCall(): void`**
166
- Answer an incoming call.
104
+ - `initialize(): Promise<void>` - Connect to the SIP server.
105
+ - `call(number, options?): Promise<Call>` - Initiate an outbound call.
106
+ - `answerCall(): void` - Answer a pending incoming call.
107
+ - `hangup(): void` - End the current active call.
108
+ - `on(event, handler): void` - Listen for events (e.g., `call:incoming`, `connection:status`).
109
+ - `destroy(): void` - Cleanup and disconnect.
167
110
 
168
- **`getCurrentCall(): Call | null`**
169
- Get the current active call.
111
+ ## Events
170
112
 
171
- **`getStatus(): ConnectionStatus`**
172
- Get current connection status.
173
-
174
- **`getExtensions(): string[]`**
175
- Get list of available extensions.
176
-
177
- **`on(event, handler): void`**
178
- Register event listener.
179
-
180
- **`off(event, handler): void`**
181
- Remove event listener.
182
-
183
- **`destroy(): void`**
184
- Cleanup and destroy SDK instance.
185
-
186
- ### Events
187
-
188
- ```typescript
189
- sdk.on('connection:status', (state: ConnectionState) => {});
190
- sdk.on('call:incoming', (call: Call) => {});
191
- sdk.on('call:outgoing', (call: Call) => {});
192
- sdk.on('call:ringing', (call: Call) => {});
193
- sdk.on('call:connected', (call: Call) => {});
194
- sdk.on('call:ended', (call: Call, reason?: string) => {});
195
- sdk.on('call:failed', (call: Call, error: string) => {});
196
- sdk.on('error', (error: Error) => {});
197
- ```
198
-
199
- ### Call Object
200
-
201
- ```typescript
202
- interface Call {
203
- id: string;
204
- status: CallStatus;
205
- direction: 'inbound' | 'outbound';
206
- remoteNumber: string;
207
- localExtension: string;
208
- duration: number;
209
-
210
- mute(): void;
211
- unmute(): void;
212
- hangup(): void;
213
- isMuted(): boolean;
214
- }
215
- ```
216
-
217
- ## Authentication
218
-
219
- ### Getting an API Token
220
-
221
- 1. Log in to your Dora Cell dashboard
222
- 2. Navigate to Settings → API Tokens
223
- 3. Generate a new API token
224
- 4. Copy the token and use it in your SDK configuration
225
-
226
- ### Backend API Endpoint
227
-
228
- The SDK expects your backend to provide a `/api/sip-credentials` endpoint that:
229
- - Accepts `Authorization: Bearer <token>` header
230
- - Returns SIP credentials in this format:
231
-
232
- ```json
233
- {
234
- "ws_url": "wss://cell.usedora.com:8089/ws",
235
- "sip_uri": "sip:101@64.227.10.164",
236
- "password": "your-password",
237
- "extensions": [
238
- { "extension": "101", "displayName": "Main Line" }
239
- ]
240
- }
241
- ```
242
-
243
- ## Phone Number Formatting
244
-
245
- The SDK automatically handles Nigerian phone number formatting:
246
-
247
- - `08012345678` → `sip:2348012345678@domain`
248
- - `2348012345678` → `sip:2348012345678@domain`
249
- - `101` (extension) → `sip:101@domain`
250
-
251
- ## Error Handling
252
-
253
- ```javascript
254
- import { AuthenticationError, CallError, ConnectionError } from '@dora-cell/sdk';
255
-
256
- try {
257
- await sdk.initialize();
258
- } catch (error) {
259
- if (error instanceof AuthenticationError) {
260
- console.error('Authentication failed:', error.message);
261
- } else if (error instanceof ConnectionError) {
262
- console.error('Connection failed:', error.message);
263
- }
264
- }
265
- ```
113
+ | Event | Description | Data |
114
+ | ------------------- | ------------------------------ | ------------------------------------ |
115
+ | `connection:status` | SIP registration status change | `{ status: string, error?: string }` |
116
+ | `call:incoming` | New incoming call detected | `Call` object |
117
+ | `call:outgoing` | New outbound call started | `Call` object |
118
+ | `call:connected` | Call answered and connected | `Call` object |
119
+ | `call:ended` | Call terminated | `Call` object, `reason: string` |
120
+ | `error` | General SDK error | `Error` object |
266
121
 
267
122
  ## Examples
268
123
 
269
- See the `/examples` directory for complete working examples:
270
- - `vanilla-js/` - Pure JavaScript implementation
271
- - `react-app/` - React application
272
- - `nextjs-app/` - Next.js application
124
+ Check the [`examples/`](../../examples) directory in the main repository:
125
+
126
+ - `next-js-demo/` - Complete Next.js implementation with React components
273
127
 
274
128
  ## License
275
129
 
package/dist/index.d.mts CHANGED
@@ -60,6 +60,7 @@ interface Call {
60
60
  unmute(): void;
61
61
  hangup(): void;
62
62
  isMuted(): boolean;
63
+ getRemoteStream(): MediaStream | null;
63
64
  }
64
65
  type ConnectionStatus = 'disconnected' | 'connecting' | 'connected' | 'registered' | 'registrationFailed';
65
66
  interface ConnectionState {
@@ -113,6 +114,7 @@ declare class DoraCell {
113
114
  * Initialize the SDK - authenticate and connect to SIP server
114
115
  */
115
116
  initialize(): Promise<void>;
117
+ private waitForRegistration;
116
118
  private initializeUserAgent;
117
119
  private setupUserAgentHandlers;
118
120
  private initializeCallManager;
package/dist/index.d.ts CHANGED
@@ -60,6 +60,7 @@ interface Call {
60
60
  unmute(): void;
61
61
  hangup(): void;
62
62
  isMuted(): boolean;
63
+ getRemoteStream(): MediaStream | null;
63
64
  }
64
65
  type ConnectionStatus = 'disconnected' | 'connecting' | 'connected' | 'registered' | 'registrationFailed';
65
66
  interface ConnectionState {
@@ -113,6 +114,7 @@ declare class DoraCell {
113
114
  * Initialize the SDK - authenticate and connect to SIP server
114
115
  */
115
116
  initialize(): Promise<void>;
117
+ private waitForRegistration;
116
118
  private initializeUserAgent;
117
119
  private setupUserAgentHandlers;
118
120
  private initializeCallManager;