@ajna-inc/webrtc 0.1.1 → 0.2.1
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 +143 -17
- package/build/index.d.ts +6 -2
- package/build/index.js +5 -1
- package/build/index.js.map +1 -1
- package/build/webrtc/WebRTCApi.d.ts +90 -5
- package/build/webrtc/WebRTCApi.js +105 -2
- package/build/webrtc/WebRTCApi.js.map +1 -1
- package/build/webrtc/WebRTCEvents.d.ts +84 -5
- package/build/webrtc/WebRTCEvents.js +8 -0
- package/build/webrtc/WebRTCEvents.js.map +1 -1
- package/build/webrtc/WebRTCModule.d.ts +50 -0
- package/build/webrtc/WebRTCModule.js +17 -2
- package/build/webrtc/WebRTCModule.js.map +1 -1
- package/build/webrtc/handlers/RenegotiateHandler.d.ts +9 -0
- package/build/webrtc/handlers/RenegotiateHandler.js +31 -0
- package/build/webrtc/handlers/RenegotiateHandler.js.map +1 -0
- package/build/webrtc/handlers/index.d.ts +1 -0
- package/build/webrtc/handlers/index.js +1 -0
- package/build/webrtc/handlers/index.js.map +1 -1
- package/build/webrtc/messages/AnswerMessage.d.ts +8 -0
- package/build/webrtc/messages/AnswerMessage.js +10 -0
- package/build/webrtc/messages/AnswerMessage.js.map +1 -1
- package/build/webrtc/messages/OfferMessage.d.ts +28 -1
- package/build/webrtc/messages/OfferMessage.js +35 -1
- package/build/webrtc/messages/OfferMessage.js.map +1 -1
- package/build/webrtc/messages/ProposeMessage.d.ts +51 -0
- package/build/webrtc/messages/ProposeMessage.js +48 -2
- package/build/webrtc/messages/ProposeMessage.js.map +1 -1
- package/build/webrtc/messages/RenegotiateMessage.d.ts +52 -0
- package/build/webrtc/messages/RenegotiateMessage.js +65 -0
- package/build/webrtc/messages/RenegotiateMessage.js.map +1 -0
- package/build/webrtc/messages/index.d.ts +1 -0
- package/build/webrtc/messages/index.js +1 -0
- package/build/webrtc/messages/index.js.map +1 -1
- package/build/webrtc/services/WebRTCService.d.ts +64 -3
- package/build/webrtc/services/WebRTCService.js +115 -12
- package/build/webrtc/services/WebRTCService.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,38 +1,95 @@
|
|
|
1
|
-
# @
|
|
1
|
+
# @ajna-inc/webrtc
|
|
2
2
|
|
|
3
|
-
DIDComm v2 signaling protocol for WebRTC P2P calls.
|
|
3
|
+
DIDComm v2 signaling protocol for WebRTC P2P calls with full NAT/firewall traversal support.
|
|
4
4
|
|
|
5
5
|
- PIURI: `https://didcomm.org/webrtc/1.0`
|
|
6
|
-
- Messages: `propose`, `offer`, `answer`, `ice`, `end`
|
|
6
|
+
- Messages: `propose`, `offer`, `answer`, `ice`, `renegotiate`, `end`
|
|
7
7
|
- Advertises support via Discover Features; works with mediators and message pickup.
|
|
8
8
|
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- **Module-level ICE server defaults** - Configure STUN/TURN servers once
|
|
12
|
+
- **ICE policy control** - `all`, `relay-preferred`, or `relay-only` for strict firewall environments
|
|
13
|
+
- **ICE restart support** - Recover from failed connections
|
|
14
|
+
- **Trickle ICE** - Efficient candidate exchange
|
|
15
|
+
- **Propose message** - Share ICE servers before SDP exchange
|
|
16
|
+
|
|
9
17
|
## Install
|
|
10
18
|
|
|
11
19
|
This package is part of the monorepo. Add the module to your Agent options:
|
|
12
20
|
|
|
13
21
|
```ts
|
|
14
|
-
import { WebRTCModule } from '@
|
|
22
|
+
import { WebRTCModule } from '@ajna-inc/webrtc'
|
|
15
23
|
|
|
16
24
|
const agent = new Agent({
|
|
17
25
|
config: { /* ... */ },
|
|
18
26
|
dependencies: agentDependencies,
|
|
19
27
|
modules: {
|
|
20
|
-
webrtc: new WebRTCModule(
|
|
28
|
+
webrtc: new WebRTCModule({
|
|
29
|
+
// Configure default ICE servers (optional - has sensible defaults)
|
|
30
|
+
iceServers: [
|
|
31
|
+
{ urls: 'stun:stun.l.google.com:19302' },
|
|
32
|
+
{ urls: 'turn:turn.example.org:3478', username: 'user', credential: 'pass' },
|
|
33
|
+
],
|
|
34
|
+
// Default ICE policy: 'all' | 'relay-preferred' | 'relay-only'
|
|
35
|
+
defaultPolicy: 'relay-preferred',
|
|
36
|
+
// Enable trickle ICE by default
|
|
37
|
+
defaultTrickle: true,
|
|
38
|
+
}),
|
|
39
|
+
},
|
|
40
|
+
})
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## NAT/Firewall Traversal
|
|
44
|
+
|
|
45
|
+
For peers behind restrictive NAT or firewalls, use TURN servers:
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
const agent = new Agent({
|
|
49
|
+
modules: {
|
|
50
|
+
webrtc: new WebRTCModule({
|
|
51
|
+
iceServers: [
|
|
52
|
+
// STUN for simple NAT
|
|
53
|
+
{ urls: 'stun:stun.l.google.com:19302' },
|
|
54
|
+
// TURN for symmetric NAT and firewalls
|
|
55
|
+
{ urls: 'turn:turn.yourserver.com:3478', username: 'user', credential: 'pass' },
|
|
56
|
+
// TURNS (TLS) for stricter firewalls
|
|
57
|
+
{ urls: 'turns:turn.yourserver.com:5349', username: 'user', credential: 'pass' },
|
|
58
|
+
],
|
|
59
|
+
// Force relay-only for maximum compatibility (hides IP addresses too)
|
|
60
|
+
defaultPolicy: 'relay-only',
|
|
61
|
+
}),
|
|
21
62
|
},
|
|
22
63
|
})
|
|
23
64
|
```
|
|
24
65
|
|
|
25
66
|
## Frontend usage (browser)
|
|
26
67
|
|
|
27
|
-
Below is a
|
|
68
|
+
Below is a setup for P2P WebRTC using Credo TS for signaling.
|
|
28
69
|
|
|
29
70
|
```ts
|
|
71
|
+
// Get configured ICE servers from module
|
|
72
|
+
const iceServers = agent.modules.webrtc.getDefaultIceServers()
|
|
73
|
+
|
|
30
74
|
// Subscribe to inbound signaling
|
|
75
|
+
agent.events.on('WebRTCEvents.IncomingPropose', async ({ payload }) => {
|
|
76
|
+
const { thid, iceServers, policy, media } = payload
|
|
77
|
+
// Caller is proposing a call - you can accept by sending an offer
|
|
78
|
+
// The iceServers from propose can be used to configure RTCPeerConnection
|
|
79
|
+
console.log('Incoming call proposal:', { media, iceServers })
|
|
80
|
+
})
|
|
81
|
+
|
|
31
82
|
agent.events.on('WebRTCEvents.IncomingOffer', async ({ payload }) => {
|
|
32
|
-
const { thid, sdp, context } = payload
|
|
33
|
-
const pc = ensurePeer(thid)
|
|
34
|
-
await pc.setRemoteDescription({ type: 'offer', sdp })
|
|
83
|
+
const { thid, sdp, iceServers, policy, context } = payload
|
|
35
84
|
|
|
85
|
+
// Use ICE servers from offer (or fall back to module defaults)
|
|
86
|
+
const pc = new RTCPeerConnection({
|
|
87
|
+
iceServers: iceServers ?? agent.modules.webrtc.getDefaultIceServers(),
|
|
88
|
+
iceTransportPolicy: policy === 'relay-only' ? 'relay' : 'all',
|
|
89
|
+
})
|
|
90
|
+
peers.set(thid, pc)
|
|
91
|
+
|
|
92
|
+
await pc.setRemoteDescription({ type: 'offer', sdp })
|
|
36
93
|
const answer = await pc.createAnswer()
|
|
37
94
|
await pc.setLocalDescription(answer)
|
|
38
95
|
|
|
@@ -44,8 +101,11 @@ agent.events.on('WebRTCEvents.IncomingOffer', async ({ payload }) => {
|
|
|
44
101
|
})
|
|
45
102
|
|
|
46
103
|
agent.events.on('WebRTCEvents.IncomingAnswer', async ({ payload }) => {
|
|
47
|
-
const { thid, sdp } = payload
|
|
48
|
-
const pc =
|
|
104
|
+
const { thid, sdp, iceServers } = payload
|
|
105
|
+
const pc = peers.get(thid)
|
|
106
|
+
if (!pc) return
|
|
107
|
+
|
|
108
|
+
// If callee provided additional ICE servers, you might want to restart ICE
|
|
49
109
|
await pc.setRemoteDescription({ type: 'answer', sdp })
|
|
50
110
|
})
|
|
51
111
|
|
|
@@ -57,16 +117,41 @@ agent.events.on('WebRTCEvents.IncomingIce', async ({ payload }) => {
|
|
|
57
117
|
else await pc.addIceCandidate(candidate as RTCIceCandidateInit)
|
|
58
118
|
})
|
|
59
119
|
|
|
120
|
+
// Handle renegotiation requests (e.g., ICE restart)
|
|
121
|
+
agent.events.on('WebRTCEvents.RenegotiateRequested', async ({ payload }) => {
|
|
122
|
+
const { thid, iceRestart, iceServers, reason } = payload
|
|
123
|
+
const pc = peers.get(thid)
|
|
124
|
+
if (!pc) return
|
|
125
|
+
|
|
126
|
+
if (iceRestart) {
|
|
127
|
+
// Perform ICE restart
|
|
128
|
+
const offer = await pc.createOffer({ iceRestart: true })
|
|
129
|
+
await pc.setLocalDescription(offer)
|
|
130
|
+
// Send new offer...
|
|
131
|
+
}
|
|
132
|
+
})
|
|
133
|
+
|
|
60
134
|
// Start call (caller)
|
|
61
135
|
async function startCall(connectionId: string, localStream: MediaStream) {
|
|
62
136
|
const thid = crypto.randomUUID()
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
137
|
+
|
|
138
|
+
// Use module's default ICE servers
|
|
139
|
+
const iceServers = agent.modules.webrtc.getDefaultIceServers()
|
|
140
|
+
|
|
141
|
+
const pc = new RTCPeerConnection({ iceServers })
|
|
66
142
|
peers.set(thid, pc)
|
|
67
143
|
|
|
144
|
+
// Handle ICE connection failures
|
|
145
|
+
pc.oniceconnectionstatechange = () => {
|
|
146
|
+
if (pc.iceConnectionState === 'failed') {
|
|
147
|
+
// Request ICE restart
|
|
148
|
+
agent.modules.webrtc.restartIce({ connectionId, threadId: thid })
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
68
152
|
// Render remote stream
|
|
69
153
|
pc.ontrack = e => (remoteVideo.srcObject = e.streams[0])
|
|
154
|
+
|
|
70
155
|
// Send ICE via DIDComm
|
|
71
156
|
pc.onicecandidate = e => agent.modules.webrtc.sendIce({
|
|
72
157
|
connectionId,
|
|
@@ -74,23 +159,64 @@ async function startCall(connectionId: string, localStream: MediaStream) {
|
|
|
74
159
|
candidate: e.candidate ?? undefined,
|
|
75
160
|
endOfCandidates: e.candidate == null,
|
|
76
161
|
})
|
|
162
|
+
|
|
77
163
|
// Add local tracks
|
|
78
164
|
for (const track of localStream.getTracks()) pc.addTrack(track, localStream)
|
|
79
165
|
|
|
80
166
|
const offer = await pc.createOffer({ offerToReceiveVideo: true, offerToReceiveAudio: true })
|
|
81
167
|
await pc.setLocalDescription(offer)
|
|
82
168
|
|
|
169
|
+
// Start call - ICE servers are automatically included from module config
|
|
83
170
|
await agent.modules.webrtc.startCall({
|
|
84
171
|
connectionId,
|
|
85
172
|
threadId: thid,
|
|
86
173
|
sdp: offer.sdp!,
|
|
87
|
-
|
|
174
|
+
// Optionally override policy for this specific call
|
|
175
|
+
policy: 'relay-preferred',
|
|
176
|
+
})
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Request ICE restart when connection fails
|
|
180
|
+
async function handleConnectionFailure(connectionId: string, thid: string) {
|
|
181
|
+
await agent.modules.webrtc.restartIce({
|
|
182
|
+
connectionId,
|
|
183
|
+
threadId: thid,
|
|
184
|
+
// Optionally provide new ICE servers
|
|
185
|
+
iceServers: [{ urls: 'turn:backup-turn.example.org:3478', username: 'u', credential: 'p' }],
|
|
88
186
|
})
|
|
89
187
|
}
|
|
90
188
|
```
|
|
91
189
|
|
|
92
|
-
|
|
190
|
+
## API Reference
|
|
191
|
+
|
|
192
|
+
### WebRTCApi Methods
|
|
193
|
+
|
|
194
|
+
| Method | Description |
|
|
195
|
+
|--------|-------------|
|
|
196
|
+
| `proposeCall()` | Send a call proposal with ICE servers before offer |
|
|
197
|
+
| `startCall()` | Send SDP offer with ICE servers |
|
|
198
|
+
| `acceptCall()` | Send SDP answer |
|
|
199
|
+
| `sendIce()` | Send ICE candidate |
|
|
200
|
+
| `renegotiate()` | Request renegotiation (track changes, codec changes) |
|
|
201
|
+
| `restartIce()` | Request ICE restart (connection recovery) |
|
|
202
|
+
| `endCall()` | End the call |
|
|
203
|
+
| `getDefaultIceServers()` | Get configured default ICE servers |
|
|
204
|
+
|
|
205
|
+
### Events
|
|
206
|
+
|
|
207
|
+
| Event | Description |
|
|
208
|
+
|-------|-------------|
|
|
209
|
+
| `IncomingPropose` | Call proposal received (includes ICE servers) |
|
|
210
|
+
| `IncomingOffer` | SDP offer received |
|
|
211
|
+
| `IncomingAnswer` | SDP answer received |
|
|
212
|
+
| `IncomingIce` | ICE candidate received |
|
|
213
|
+
| `RenegotiateRequested` | Renegotiation requested (e.g., ICE restart) |
|
|
214
|
+
| `CallEnded` | Call ended |
|
|
215
|
+
|
|
216
|
+
## Notes
|
|
217
|
+
|
|
93
218
|
- This module moves only signaling over DIDComm; media flows via WebRTC/DTLS-SRTP.
|
|
94
|
-
- For NAT traversal,
|
|
219
|
+
- For NAT traversal, configure TURN servers in the module config or per-call.
|
|
220
|
+
- Use `relay-only` policy for maximum firewall compatibility (also hides IP addresses).
|
|
95
221
|
- Works with mediators and message pickup (offline delivery), as with any DIDComm message.
|
|
96
222
|
|
package/build/index.d.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
export { WebRTCModule } from './webrtc/WebRTCModule';
|
|
1
|
+
export { WebRTCModule, WebRTCModuleConfigToken } from './webrtc/WebRTCModule';
|
|
2
|
+
export type { WebRTCModuleConfig, WebRTCIceServerConfig } from './webrtc/WebRTCModule';
|
|
2
3
|
export { WebRTCApi } from './webrtc/WebRTCApi';
|
|
3
|
-
export { WebRTCEvents, type IncomingOfferEvent, type IncomingIceEvent } from './webrtc/WebRTCEvents';
|
|
4
|
+
export { WebRTCEvents, type IceServerEventConfig, type IncomingProposeEvent, type IncomingOfferEvent, type IncomingAnswerEvent, type IncomingIceEvent, type RenegotiateRequestedEvent, type CallEndedEvent, } from './webrtc/WebRTCEvents';
|
|
4
5
|
export * from './webrtc/messages';
|
|
6
|
+
export type { IcePolicy, IceServerConfig } from './webrtc/messages/OfferMessage';
|
|
7
|
+
export type { MediaType } from './webrtc/messages/ProposeMessage';
|
|
8
|
+
export type { RenegotiateReason } from './webrtc/messages/RenegotiateMessage';
|
package/build/index.js
CHANGED
|
@@ -14,12 +14,16 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.WebRTCEvents = exports.WebRTCApi = exports.WebRTCModule = void 0;
|
|
17
|
+
exports.WebRTCEvents = exports.WebRTCApi = exports.WebRTCModuleConfigToken = exports.WebRTCModule = void 0;
|
|
18
|
+
// Module and API
|
|
18
19
|
var WebRTCModule_1 = require("./webrtc/WebRTCModule");
|
|
19
20
|
Object.defineProperty(exports, "WebRTCModule", { enumerable: true, get: function () { return WebRTCModule_1.WebRTCModule; } });
|
|
21
|
+
Object.defineProperty(exports, "WebRTCModuleConfigToken", { enumerable: true, get: function () { return WebRTCModule_1.WebRTCModuleConfigToken; } });
|
|
20
22
|
var WebRTCApi_1 = require("./webrtc/WebRTCApi");
|
|
21
23
|
Object.defineProperty(exports, "WebRTCApi", { enumerable: true, get: function () { return WebRTCApi_1.WebRTCApi; } });
|
|
24
|
+
// Events
|
|
22
25
|
var WebRTCEvents_1 = require("./webrtc/WebRTCEvents");
|
|
23
26
|
Object.defineProperty(exports, "WebRTCEvents", { enumerable: true, get: function () { return WebRTCEvents_1.WebRTCEvents; } });
|
|
27
|
+
// Messages
|
|
24
28
|
__exportStar(require("./webrtc/messages"), exports);
|
|
25
29
|
//# sourceMappingURL=index.js.map
|
package/build/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,iBAAiB;AACjB,sDAA6E;AAApE,4GAAA,YAAY,OAAA;AAAE,uHAAA,uBAAuB,OAAA;AAE9C,gDAA8C;AAArC,sGAAA,SAAS,OAAA;AAElB,SAAS;AACT,sDAS8B;AAR5B,4GAAA,YAAY,OAAA;AAUd,WAAW;AACX,oDAAiC"}
|
|
@@ -1,29 +1,75 @@
|
|
|
1
1
|
import { ConnectionService, MessageSender, AgentContext } from '@credo-ts/core';
|
|
2
2
|
import { WebRTCService } from './services/WebRTCService';
|
|
3
|
+
import type { IcePolicy, IceServerConfig } from './messages/OfferMessage';
|
|
4
|
+
import type { MediaType } from './messages/ProposeMessage';
|
|
5
|
+
import type { RenegotiateReason } from './messages/RenegotiateMessage';
|
|
6
|
+
import { type WebRTCModuleConfig } from './WebRTCModule';
|
|
3
7
|
export declare class WebRTCApi {
|
|
4
8
|
private connectionService;
|
|
5
9
|
private messageSender;
|
|
6
10
|
private webrtcService;
|
|
7
11
|
private agentContext;
|
|
12
|
+
private config;
|
|
8
13
|
constructor(connectionService: ConnectionService, messageSender: MessageSender, webrtcService: WebRTCService, agentContext: AgentContext);
|
|
9
14
|
onAgentReady: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Get the configured default ICE servers
|
|
17
|
+
*/
|
|
18
|
+
getDefaultIceServers(): WebRTCModuleConfig['iceServers'];
|
|
19
|
+
/**
|
|
20
|
+
* Propose a call to a peer (before sending offer)
|
|
21
|
+
* This allows sharing ICE servers and negotiating capabilities before the SDP exchange
|
|
22
|
+
*/
|
|
23
|
+
proposeCall(options: {
|
|
24
|
+
connectionId: string;
|
|
25
|
+
threadId?: string;
|
|
26
|
+
parentThreadId?: string;
|
|
27
|
+
/** Requested media types */
|
|
28
|
+
media?: MediaType[];
|
|
29
|
+
/** Whether data channel is requested */
|
|
30
|
+
data?: boolean;
|
|
31
|
+
/** Topology: 'mesh' (P2P) or 'sfu' */
|
|
32
|
+
topology?: 'mesh' | 'sfu';
|
|
33
|
+
/** Whether trickle ICE is supported (defaults to module config) */
|
|
34
|
+
trickle?: boolean;
|
|
35
|
+
/** ICE policy (defaults to module config) */
|
|
36
|
+
policy?: IcePolicy;
|
|
37
|
+
/** ICE servers - uses module defaults if not provided */
|
|
38
|
+
iceServers?: IceServerConfig[];
|
|
39
|
+
/** Optional reason/context */
|
|
40
|
+
reason?: string;
|
|
41
|
+
}): Promise<{
|
|
42
|
+
threadId: string;
|
|
43
|
+
}>;
|
|
44
|
+
/**
|
|
45
|
+
* Start a call by sending an SDP offer
|
|
46
|
+
*/
|
|
10
47
|
startCall(options: {
|
|
11
48
|
connectionId: string;
|
|
12
49
|
threadId: string;
|
|
13
50
|
parentThreadId?: string;
|
|
14
51
|
sdp: string;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
52
|
+
/** ICE servers - uses module defaults if not provided */
|
|
53
|
+
iceServers?: IceServerConfig[];
|
|
54
|
+
/** ICE policy (defaults to module config) */
|
|
55
|
+
policy?: IcePolicy;
|
|
56
|
+
/** Whether trickle ICE is enabled (defaults to module config) */
|
|
57
|
+
trickle?: boolean;
|
|
20
58
|
}): Promise<import("./repository/WebRTCCallRecord").WebRTCCallRecord>;
|
|
59
|
+
/**
|
|
60
|
+
* Accept a call by sending an SDP answer
|
|
61
|
+
*/
|
|
21
62
|
acceptCall(options: {
|
|
22
63
|
connectionId: string;
|
|
23
64
|
threadId: string;
|
|
24
65
|
parentThreadId?: string;
|
|
25
66
|
sdp: string;
|
|
67
|
+
/** Optional ICE servers from callee (if different from caller's) */
|
|
68
|
+
iceServers?: IceServerConfig[];
|
|
26
69
|
}): Promise<void>;
|
|
70
|
+
/**
|
|
71
|
+
* Send an ICE candidate
|
|
72
|
+
*/
|
|
27
73
|
sendIce(options: {
|
|
28
74
|
connectionId: string;
|
|
29
75
|
threadId: string;
|
|
@@ -31,6 +77,45 @@ export declare class WebRTCApi {
|
|
|
31
77
|
candidate?: Record<string, unknown>;
|
|
32
78
|
endOfCandidates?: boolean;
|
|
33
79
|
}): Promise<void>;
|
|
80
|
+
/**
|
|
81
|
+
* Request renegotiation (for ICE restart, adding/removing tracks, etc.)
|
|
82
|
+
*
|
|
83
|
+
* Use this when:
|
|
84
|
+
* - ICE connection failed and needs restart
|
|
85
|
+
* - Adding screenshare or switching cameras
|
|
86
|
+
* - Network changed (WiFi to cellular)
|
|
87
|
+
* - Changing codec or bandwidth settings
|
|
88
|
+
*/
|
|
89
|
+
renegotiate(options: {
|
|
90
|
+
connectionId: string;
|
|
91
|
+
threadId: string;
|
|
92
|
+
parentThreadId?: string;
|
|
93
|
+
/** Reason for renegotiation */
|
|
94
|
+
reason: RenegotiateReason | string;
|
|
95
|
+
/** Whether to perform ICE restart (required for recovering failed connections) */
|
|
96
|
+
iceRestart?: boolean;
|
|
97
|
+
/** New ICE servers (useful when switching networks) */
|
|
98
|
+
iceServers?: IceServerConfig[];
|
|
99
|
+
/** Updated ICE policy */
|
|
100
|
+
policy?: IcePolicy;
|
|
101
|
+
}): Promise<void>;
|
|
102
|
+
/**
|
|
103
|
+
* Request ICE restart (convenience method for renegotiate with iceRestart=true)
|
|
104
|
+
*
|
|
105
|
+
* Use when the WebRTC connection has failed or disconnected
|
|
106
|
+
*/
|
|
107
|
+
restartIce(options: {
|
|
108
|
+
connectionId: string;
|
|
109
|
+
threadId: string;
|
|
110
|
+
parentThreadId?: string;
|
|
111
|
+
/** New ICE servers (optional, useful when original servers are unreachable) */
|
|
112
|
+
iceServers?: IceServerConfig[];
|
|
113
|
+
/** Updated ICE policy */
|
|
114
|
+
policy?: IcePolicy;
|
|
115
|
+
}): Promise<void>;
|
|
116
|
+
/**
|
|
117
|
+
* End a call
|
|
118
|
+
*/
|
|
34
119
|
endCall(options: {
|
|
35
120
|
connectionId: string;
|
|
36
121
|
threadId: string;
|
|
@@ -15,6 +15,7 @@ const tsyringe_1 = require("tsyringe");
|
|
|
15
15
|
const core_2 = require("@credo-ts/core");
|
|
16
16
|
const WebRTCService_1 = require("./services/WebRTCService");
|
|
17
17
|
const handlers_1 = require("./handlers");
|
|
18
|
+
const WebRTCModule_1 = require("./WebRTCModule");
|
|
18
19
|
let WebRTCApi = class WebRTCApi {
|
|
19
20
|
constructor(connectionService, messageSender, webrtcService, agentContext) {
|
|
20
21
|
this.connectionService = connectionService;
|
|
@@ -27,15 +28,71 @@ let WebRTCApi = class WebRTCApi {
|
|
|
27
28
|
new handlers_1.OfferHandler(this.webrtcService),
|
|
28
29
|
new handlers_1.AnswerHandler(this.webrtcService),
|
|
29
30
|
new handlers_1.IceHandler(this.webrtcService),
|
|
31
|
+
new handlers_1.RenegotiateHandler(this.webrtcService),
|
|
30
32
|
new handlers_1.EndHandler(this.webrtcService),
|
|
31
33
|
new handlers_1.ProposeHandler(this.webrtcService),
|
|
32
34
|
]);
|
|
33
35
|
return true;
|
|
34
36
|
})();
|
|
37
|
+
// Get config from dependency manager, with fallback defaults
|
|
38
|
+
try {
|
|
39
|
+
this.config = this.agentContext.dependencyManager.resolve(WebRTCModule_1.WebRTCModuleConfigToken);
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
this.config = {
|
|
43
|
+
iceServers: [
|
|
44
|
+
{ urls: 'stun:stun.l.google.com:19302' },
|
|
45
|
+
{ urls: 'stun:stun1.l.google.com:19302' },
|
|
46
|
+
],
|
|
47
|
+
defaultPolicy: 'all',
|
|
48
|
+
defaultTrickle: true,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
35
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* Get the configured default ICE servers
|
|
54
|
+
*/
|
|
55
|
+
getDefaultIceServers() {
|
|
56
|
+
return this.config.iceServers;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Propose a call to a peer (before sending offer)
|
|
60
|
+
* This allows sharing ICE servers and negotiating capabilities before the SDP exchange
|
|
61
|
+
*/
|
|
62
|
+
async proposeCall(options) {
|
|
63
|
+
const connection = await this.connectionService.getById(this.agentContext, options.connectionId);
|
|
64
|
+
// Use module defaults for missing options
|
|
65
|
+
const iceServers = options.iceServers ?? this.config.iceServers;
|
|
66
|
+
const policy = options.policy ?? this.config.defaultPolicy;
|
|
67
|
+
const trickle = options.trickle ?? this.config.defaultTrickle;
|
|
68
|
+
const { message } = this.webrtcService.createPropose({
|
|
69
|
+
threadId: options.threadId,
|
|
70
|
+
parentThreadId: options.parentThreadId,
|
|
71
|
+
media: options.media,
|
|
72
|
+
data: options.data,
|
|
73
|
+
topology: options.topology ?? 'mesh',
|
|
74
|
+
trickle,
|
|
75
|
+
policy,
|
|
76
|
+
iceServers,
|
|
77
|
+
reason: options.reason,
|
|
78
|
+
});
|
|
79
|
+
const outbound = await (0, core_2.getOutboundMessageContext)(this.agentContext, {
|
|
80
|
+
message,
|
|
81
|
+
connectionRecord: connection,
|
|
82
|
+
});
|
|
83
|
+
await this.messageSender.sendMessage(outbound);
|
|
84
|
+
return { threadId: message.threadId ?? message.id };
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Start a call by sending an SDP offer
|
|
88
|
+
*/
|
|
36
89
|
async startCall(options) {
|
|
37
90
|
const connection = await this.connectionService.getById(this.agentContext, options.connectionId);
|
|
38
|
-
|
|
91
|
+
// Use module defaults for missing options
|
|
92
|
+
const iceServers = options.iceServers ?? this.config.iceServers;
|
|
93
|
+
const policy = options.policy ?? this.config.defaultPolicy;
|
|
94
|
+
const trickle = options.trickle ?? this.config.defaultTrickle;
|
|
95
|
+
const { message, record } = this.webrtcService.createOffer(this.agentContext, connection, options.threadId, options.parentThreadId, options.sdp, iceServers, policy, trickle);
|
|
39
96
|
const outbound = await (0, core_2.getOutboundMessageContext)(this.agentContext, {
|
|
40
97
|
message,
|
|
41
98
|
associatedRecord: record,
|
|
@@ -44,15 +101,21 @@ let WebRTCApi = class WebRTCApi {
|
|
|
44
101
|
await this.messageSender.sendMessage(outbound);
|
|
45
102
|
return record;
|
|
46
103
|
}
|
|
104
|
+
/**
|
|
105
|
+
* Accept a call by sending an SDP answer
|
|
106
|
+
*/
|
|
47
107
|
async acceptCall(options) {
|
|
48
108
|
const connection = await this.connectionService.getById(this.agentContext, options.connectionId);
|
|
49
|
-
const { message } = this.webrtcService.createAnswer(this.agentContext, connection, options.threadId, options.parentThreadId, options.sdp);
|
|
109
|
+
const { message } = this.webrtcService.createAnswer(this.agentContext, connection, options.threadId, options.parentThreadId, options.sdp, options.iceServers);
|
|
50
110
|
const outbound = await (0, core_2.getOutboundMessageContext)(this.agentContext, {
|
|
51
111
|
message,
|
|
52
112
|
connectionRecord: connection,
|
|
53
113
|
});
|
|
54
114
|
await this.messageSender.sendMessage(outbound);
|
|
55
115
|
}
|
|
116
|
+
/**
|
|
117
|
+
* Send an ICE candidate
|
|
118
|
+
*/
|
|
56
119
|
async sendIce(options) {
|
|
57
120
|
const connection = await this.connectionService.getById(this.agentContext, options.connectionId);
|
|
58
121
|
const message = this.webrtcService.createIce(options.threadId, options.parentThreadId, options.candidate, options.endOfCandidates);
|
|
@@ -62,6 +125,46 @@ let WebRTCApi = class WebRTCApi {
|
|
|
62
125
|
});
|
|
63
126
|
await this.messageSender.sendMessage(outbound);
|
|
64
127
|
}
|
|
128
|
+
/**
|
|
129
|
+
* Request renegotiation (for ICE restart, adding/removing tracks, etc.)
|
|
130
|
+
*
|
|
131
|
+
* Use this when:
|
|
132
|
+
* - ICE connection failed and needs restart
|
|
133
|
+
* - Adding screenshare or switching cameras
|
|
134
|
+
* - Network changed (WiFi to cellular)
|
|
135
|
+
* - Changing codec or bandwidth settings
|
|
136
|
+
*/
|
|
137
|
+
async renegotiate(options) {
|
|
138
|
+
const connection = await this.connectionService.getById(this.agentContext, options.connectionId);
|
|
139
|
+
const message = this.webrtcService.createRenegotiate({
|
|
140
|
+
threadId: options.threadId,
|
|
141
|
+
parentThreadId: options.parentThreadId,
|
|
142
|
+
reason: options.reason,
|
|
143
|
+
iceRestart: options.iceRestart,
|
|
144
|
+
iceServers: options.iceServers,
|
|
145
|
+
policy: options.policy,
|
|
146
|
+
});
|
|
147
|
+
const outbound = await (0, core_2.getOutboundMessageContext)(this.agentContext, {
|
|
148
|
+
message,
|
|
149
|
+
connectionRecord: connection,
|
|
150
|
+
});
|
|
151
|
+
await this.messageSender.sendMessage(outbound);
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Request ICE restart (convenience method for renegotiate with iceRestart=true)
|
|
155
|
+
*
|
|
156
|
+
* Use when the WebRTC connection has failed or disconnected
|
|
157
|
+
*/
|
|
158
|
+
async restartIce(options) {
|
|
159
|
+
return this.renegotiate({
|
|
160
|
+
...options,
|
|
161
|
+
reason: 'ice-restart',
|
|
162
|
+
iceRestart: true,
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* End a call
|
|
167
|
+
*/
|
|
65
168
|
async endCall(options) {
|
|
66
169
|
const connection = await this.connectionService.getById(this.agentContext, options.connectionId);
|
|
67
170
|
const message = this.webrtcService.createEnd(options.threadId, options.parentThreadId, options.reason);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WebRTCApi.js","sourceRoot":"","sources":["../../src/webrtc/WebRTCApi.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,yCAA+E;AAE/E,uCAAqC;AACrC,yCAA0D;AAE1D,4DAAwD;
|
|
1
|
+
{"version":3,"file":"WebRTCApi.js","sourceRoot":"","sources":["../../src/webrtc/WebRTCApi.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,27 +1,81 @@
|
|
|
1
1
|
import type { InboundMessageContext } from '@credo-ts/core';
|
|
2
|
+
import type { IcePolicy } from './messages/OfferMessage';
|
|
3
|
+
import type { MediaType } from './messages/ProposeMessage';
|
|
4
|
+
import type { RenegotiateReason } from './messages/RenegotiateMessage';
|
|
2
5
|
export declare enum WebRTCEvents {
|
|
6
|
+
/** Incoming call proposal (before offer) */
|
|
7
|
+
IncomingPropose = "WebRTCEvents.IncomingPropose",
|
|
8
|
+
/** Incoming SDP offer */
|
|
3
9
|
IncomingOffer = "WebRTCEvents.IncomingOffer",
|
|
10
|
+
/** Incoming SDP answer */
|
|
4
11
|
IncomingAnswer = "WebRTCEvents.IncomingAnswer",
|
|
12
|
+
/** Incoming ICE candidate */
|
|
5
13
|
IncomingIce = "WebRTCEvents.IncomingIce",
|
|
14
|
+
/** Renegotiation requested (track changes, ICE restart) */
|
|
15
|
+
RenegotiateRequested = "WebRTCEvents.RenegotiateRequested",
|
|
16
|
+
/** Call ended */
|
|
6
17
|
CallEnded = "WebRTCEvents.CallEnded"
|
|
7
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* ICE server configuration in events
|
|
21
|
+
*/
|
|
22
|
+
export interface IceServerEventConfig {
|
|
23
|
+
urls: string | string[];
|
|
24
|
+
username?: string;
|
|
25
|
+
credential?: string;
|
|
26
|
+
credentialType?: 'password' | 'oauth';
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Event emitted when a call proposal is received
|
|
30
|
+
*/
|
|
31
|
+
export interface IncomingProposeEvent {
|
|
32
|
+
context: InboundMessageContext;
|
|
33
|
+
thid: string;
|
|
34
|
+
pthid?: string;
|
|
35
|
+
/** Requested media types */
|
|
36
|
+
media?: MediaType[];
|
|
37
|
+
/** Whether data channel is requested */
|
|
38
|
+
data?: boolean;
|
|
39
|
+
/** Topology: 'mesh' or 'sfu' */
|
|
40
|
+
topology?: 'mesh' | 'sfu';
|
|
41
|
+
/** Whether trickle ICE is supported */
|
|
42
|
+
trickle?: boolean;
|
|
43
|
+
/** ICE policy */
|
|
44
|
+
policy?: IcePolicy;
|
|
45
|
+
/** ICE servers for NAT traversal */
|
|
46
|
+
iceServers?: IceServerEventConfig[];
|
|
47
|
+
/** Optional reason/context */
|
|
48
|
+
reason?: string;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Event emitted when an SDP offer is received
|
|
52
|
+
*/
|
|
8
53
|
export interface IncomingOfferEvent {
|
|
9
54
|
context: InboundMessageContext;
|
|
10
55
|
thid: string;
|
|
11
56
|
pthid?: string;
|
|
12
57
|
sdp: string;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
58
|
+
/** ICE servers for NAT traversal */
|
|
59
|
+
iceServers?: IceServerEventConfig[];
|
|
60
|
+
/** ICE policy */
|
|
61
|
+
policy?: IcePolicy;
|
|
62
|
+
/** Whether trickle ICE is enabled */
|
|
63
|
+
trickle?: boolean;
|
|
18
64
|
}
|
|
65
|
+
/**
|
|
66
|
+
* Event emitted when an SDP answer is received
|
|
67
|
+
*/
|
|
19
68
|
export interface IncomingAnswerEvent {
|
|
20
69
|
context: InboundMessageContext;
|
|
21
70
|
thid: string;
|
|
22
71
|
pthid?: string;
|
|
23
72
|
sdp: string;
|
|
73
|
+
/** Optional ICE servers from callee */
|
|
74
|
+
iceServers?: IceServerEventConfig[];
|
|
24
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* Event emitted when an ICE candidate is received
|
|
78
|
+
*/
|
|
25
79
|
export interface IncomingIceEvent {
|
|
26
80
|
context: InboundMessageContext;
|
|
27
81
|
thid: string;
|
|
@@ -29,3 +83,28 @@ export interface IncomingIceEvent {
|
|
|
29
83
|
candidate: Record<string, unknown>;
|
|
30
84
|
endOfCandidates?: boolean;
|
|
31
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* Event emitted when renegotiation is requested
|
|
88
|
+
*/
|
|
89
|
+
export interface RenegotiateRequestedEvent {
|
|
90
|
+
context: InboundMessageContext;
|
|
91
|
+
thid: string;
|
|
92
|
+
pthid?: string;
|
|
93
|
+
/** Reason for renegotiation */
|
|
94
|
+
reason: RenegotiateReason | string;
|
|
95
|
+
/** Whether ICE restart is requested */
|
|
96
|
+
iceRestart?: boolean;
|
|
97
|
+
/** New ICE servers (if changed) */
|
|
98
|
+
iceServers?: IceServerEventConfig[];
|
|
99
|
+
/** Updated ICE policy */
|
|
100
|
+
policy?: IcePolicy;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Event emitted when a call ends
|
|
104
|
+
*/
|
|
105
|
+
export interface CallEndedEvent {
|
|
106
|
+
context: InboundMessageContext;
|
|
107
|
+
thid: string;
|
|
108
|
+
pthid?: string;
|
|
109
|
+
reason?: string;
|
|
110
|
+
}
|