@ajna-inc/webrtc 0.2.1 → 0.6.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.
Files changed (134) hide show
  1. package/.npmvc/attestations.jsonld +32 -0
  2. package/build/_virtual/_@oxc-project_runtime@0.99.0/helpers/decorate.mjs +10 -0
  3. package/build/_virtual/_@oxc-project_runtime@0.99.0/helpers/decorateMetadata.mjs +7 -0
  4. package/build/_virtual/_@oxc-project_runtime@0.99.0/helpers/decorateParam.mjs +9 -0
  5. package/build/index.d.mts +11 -0
  6. package/build/index.mjs +12 -0
  7. package/build/webrtc/WebRTCApi.d.mts +131 -0
  8. package/build/webrtc/WebRTCApi.d.mts.map +1 -0
  9. package/build/webrtc/WebRTCApi.mjs +161 -0
  10. package/build/webrtc/WebRTCApi.mjs.map +1 -0
  11. package/build/webrtc/WebRTCEvents.d.mts +115 -0
  12. package/build/webrtc/WebRTCEvents.d.mts.map +1 -0
  13. package/build/webrtc/WebRTCEvents.mjs +20 -0
  14. package/build/webrtc/WebRTCEvents.mjs.map +1 -0
  15. package/build/webrtc/WebRTCModule.d.mts +63 -0
  16. package/build/webrtc/WebRTCModule.d.mts.map +1 -0
  17. package/build/webrtc/WebRTCModule.mjs +51 -0
  18. package/build/webrtc/WebRTCModule.mjs.map +1 -0
  19. package/build/webrtc/handlers/AnswerHandler.mjs +23 -0
  20. package/build/webrtc/handlers/AnswerHandler.mjs.map +1 -0
  21. package/build/webrtc/handlers/EndHandler.mjs +23 -0
  22. package/build/webrtc/handlers/EndHandler.mjs.map +1 -0
  23. package/build/webrtc/handlers/IceHandler.mjs +23 -0
  24. package/build/webrtc/handlers/IceHandler.mjs.map +1 -0
  25. package/build/webrtc/handlers/OfferHandler.mjs +23 -0
  26. package/build/webrtc/handlers/OfferHandler.mjs.map +1 -0
  27. package/build/webrtc/handlers/ProposeHandler.mjs +23 -0
  28. package/build/webrtc/handlers/ProposeHandler.mjs.map +1 -0
  29. package/build/webrtc/handlers/RenegotiateHandler.mjs +23 -0
  30. package/build/webrtc/handlers/RenegotiateHandler.mjs.map +1 -0
  31. package/build/webrtc/handlers/index.mjs +6 -0
  32. package/build/webrtc/messages/AnswerMessage.d.mts +29 -0
  33. package/build/webrtc/messages/AnswerMessage.d.mts.map +1 -0
  34. package/build/webrtc/messages/AnswerMessage.mjs +44 -0
  35. package/build/webrtc/messages/AnswerMessage.mjs.map +1 -0
  36. package/build/webrtc/messages/EndMessage.d.mts +19 -0
  37. package/build/webrtc/messages/EndMessage.d.mts.map +1 -0
  38. package/build/webrtc/messages/EndMessage.mjs +31 -0
  39. package/build/webrtc/messages/EndMessage.mjs.map +1 -0
  40. package/build/webrtc/messages/IceMessage.d.mts +21 -0
  41. package/build/webrtc/messages/IceMessage.d.mts.map +1 -0
  42. package/build/webrtc/messages/IceMessage.mjs +38 -0
  43. package/build/webrtc/messages/IceMessage.mjs.map +1 -0
  44. package/build/webrtc/messages/OfferMessage.d.mts +56 -0
  45. package/build/webrtc/messages/OfferMessage.d.mts.map +1 -0
  46. package/build/webrtc/messages/OfferMessage.mjs +86 -0
  47. package/build/webrtc/messages/OfferMessage.mjs.map +1 -0
  48. package/build/webrtc/messages/ProposeMessage.d.mts +70 -0
  49. package/build/webrtc/messages/ProposeMessage.d.mts.map +1 -0
  50. package/build/webrtc/messages/ProposeMessage.mjs +76 -0
  51. package/build/webrtc/messages/ProposeMessage.mjs.map +1 -0
  52. package/build/webrtc/messages/RenegotiateMessage.d.mts +59 -0
  53. package/build/webrtc/messages/RenegotiateMessage.d.mts.map +1 -0
  54. package/build/webrtc/messages/RenegotiateMessage.mjs +56 -0
  55. package/build/webrtc/messages/RenegotiateMessage.mjs.map +1 -0
  56. package/build/webrtc/messages/index.d.mts +6 -0
  57. package/build/webrtc/messages/index.mjs +6 -0
  58. package/build/webrtc/repository/WebRTCCallRecord.d.mts +32 -0
  59. package/build/webrtc/repository/WebRTCCallRecord.d.mts.map +1 -0
  60. package/build/webrtc/repository/WebRTCCallRecord.mjs +31 -0
  61. package/build/webrtc/repository/WebRTCCallRecord.mjs.map +1 -0
  62. package/build/webrtc/repository/WebRTCCallRepository.d.mts +10 -0
  63. package/build/webrtc/repository/WebRTCCallRepository.d.mts.map +1 -0
  64. package/build/webrtc/repository/WebRTCCallRepository.mjs +23 -0
  65. package/build/webrtc/repository/WebRTCCallRepository.mjs.map +1 -0
  66. package/build/webrtc/services/WebRTCService.d.mts +93 -0
  67. package/build/webrtc/services/WebRTCService.d.mts.map +1 -0
  68. package/build/webrtc/services/WebRTCService.mjs +244 -0
  69. package/build/webrtc/services/WebRTCService.mjs.map +1 -0
  70. package/package.json +19 -15
  71. package/README.md +0 -222
  72. package/build/index.d.ts +0 -8
  73. package/build/index.js +0 -29
  74. package/build/index.js.map +0 -1
  75. package/build/webrtc/WebRTCApi.d.ts +0 -125
  76. package/build/webrtc/WebRTCApi.js +0 -186
  77. package/build/webrtc/WebRTCApi.js.map +0 -1
  78. package/build/webrtc/WebRTCEvents.d.ts +0 -110
  79. package/build/webrtc/WebRTCEvents.js +0 -19
  80. package/build/webrtc/WebRTCEvents.js.map +0 -1
  81. package/build/webrtc/WebRTCModule.d.ts +0 -56
  82. package/build/webrtc/WebRTCModule.js +0 -40
  83. package/build/webrtc/WebRTCModule.js.map +0 -1
  84. package/build/webrtc/handlers/AnswerHandler.d.ts +0 -9
  85. package/build/webrtc/handlers/AnswerHandler.js +0 -31
  86. package/build/webrtc/handlers/AnswerHandler.js.map +0 -1
  87. package/build/webrtc/handlers/EndHandler.d.ts +0 -9
  88. package/build/webrtc/handlers/EndHandler.js +0 -31
  89. package/build/webrtc/handlers/EndHandler.js.map +0 -1
  90. package/build/webrtc/handlers/IceHandler.d.ts +0 -9
  91. package/build/webrtc/handlers/IceHandler.js +0 -31
  92. package/build/webrtc/handlers/IceHandler.js.map +0 -1
  93. package/build/webrtc/handlers/OfferHandler.d.ts +0 -9
  94. package/build/webrtc/handlers/OfferHandler.js +0 -31
  95. package/build/webrtc/handlers/OfferHandler.js.map +0 -1
  96. package/build/webrtc/handlers/ProposeHandler.d.ts +0 -9
  97. package/build/webrtc/handlers/ProposeHandler.js +0 -31
  98. package/build/webrtc/handlers/ProposeHandler.js.map +0 -1
  99. package/build/webrtc/handlers/RenegotiateHandler.d.ts +0 -9
  100. package/build/webrtc/handlers/RenegotiateHandler.js +0 -31
  101. package/build/webrtc/handlers/RenegotiateHandler.js.map +0 -1
  102. package/build/webrtc/handlers/index.d.ts +0 -6
  103. package/build/webrtc/handlers/index.js +0 -23
  104. package/build/webrtc/handlers/index.js.map +0 -1
  105. package/build/webrtc/messages/AnswerMessage.d.ts +0 -23
  106. package/build/webrtc/messages/AnswerMessage.js +0 -52
  107. package/build/webrtc/messages/AnswerMessage.js.map +0 -1
  108. package/build/webrtc/messages/EndMessage.d.ts +0 -13
  109. package/build/webrtc/messages/EndMessage.js +0 -37
  110. package/build/webrtc/messages/EndMessage.js.map +0 -1
  111. package/build/webrtc/messages/IceMessage.d.ts +0 -15
  112. package/build/webrtc/messages/IceMessage.js +0 -43
  113. package/build/webrtc/messages/IceMessage.js.map +0 -1
  114. package/build/webrtc/messages/OfferMessage.d.ts +0 -49
  115. package/build/webrtc/messages/OfferMessage.js +0 -102
  116. package/build/webrtc/messages/OfferMessage.js.map +0 -1
  117. package/build/webrtc/messages/ProposeMessage.d.ts +0 -63
  118. package/build/webrtc/messages/ProposeMessage.js +0 -84
  119. package/build/webrtc/messages/ProposeMessage.js.map +0 -1
  120. package/build/webrtc/messages/RenegotiateMessage.d.ts +0 -52
  121. package/build/webrtc/messages/RenegotiateMessage.js +0 -65
  122. package/build/webrtc/messages/RenegotiateMessage.js.map +0 -1
  123. package/build/webrtc/messages/index.d.ts +0 -6
  124. package/build/webrtc/messages/index.js +0 -23
  125. package/build/webrtc/messages/index.js.map +0 -1
  126. package/build/webrtc/repository/WebRTCCallRecord.d.ts +0 -29
  127. package/build/webrtc/repository/WebRTCCallRecord.js +0 -30
  128. package/build/webrtc/repository/WebRTCCallRecord.js.map +0 -1
  129. package/build/webrtc/repository/WebRTCCallRepository.d.ts +0 -5
  130. package/build/webrtc/repository/WebRTCCallRepository.js +0 -30
  131. package/build/webrtc/repository/WebRTCCallRepository.js.map +0 -1
  132. package/build/webrtc/services/WebRTCService.d.ts +0 -86
  133. package/build/webrtc/services/WebRTCService.js +0 -229
  134. package/build/webrtc/services/WebRTCService.js.map +0 -1
@@ -0,0 +1,244 @@
1
+ import { __decorateMetadata } from "../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorateMetadata.mjs";
2
+ import { __decorate } from "../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorate.mjs";
3
+ import { OfferMessage } from "../messages/OfferMessage.mjs";
4
+ import { ProposeMessage } from "../messages/ProposeMessage.mjs";
5
+ import { AnswerMessage } from "../messages/AnswerMessage.mjs";
6
+ import { IceMessage } from "../messages/IceMessage.mjs";
7
+ import { RenegotiateMessage } from "../messages/RenegotiateMessage.mjs";
8
+ import { EndMessage } from "../messages/EndMessage.mjs";
9
+ import "../messages/index.mjs";
10
+ import { WebRTCEvents } from "../WebRTCEvents.mjs";
11
+ import { WebRTCCallRecord } from "../repository/WebRTCCallRecord.mjs";
12
+ import { WebRTCCallRepository } from "../repository/WebRTCCallRepository.mjs";
13
+ import { EventEmitter } from "@credo-ts/core";
14
+ import { injectable } from "tsyringe";
15
+
16
+ //#region src/webrtc/services/WebRTCService.ts
17
+ var _ref, _ref2;
18
+ let WebRTCService = class WebRTCService$1 {
19
+ constructor(repo, events) {
20
+ this.repo = repo;
21
+ this.events = events;
22
+ }
23
+ /**
24
+ * Create a propose message to initiate a call
25
+ */
26
+ createPropose(options) {
27
+ return { message: new ProposeMessage({
28
+ threadId: options.threadId,
29
+ parentThreadId: options.parentThreadId,
30
+ media: options.media,
31
+ data: options.data,
32
+ topology: options.topology,
33
+ trickle: options.trickle,
34
+ policy: options.policy,
35
+ iceServers: options.iceServers,
36
+ reason: options.reason
37
+ }) };
38
+ }
39
+ /**
40
+ * Create an offer message with SDP
41
+ */
42
+ createOffer(agentContext, connection, threadId, parentThreadId, sdp, iceServers, policy, trickle) {
43
+ return {
44
+ message: new OfferMessage({
45
+ threadId,
46
+ parentThreadId,
47
+ sdp,
48
+ iceServers,
49
+ policy,
50
+ trickle
51
+ }),
52
+ record: new WebRTCCallRecord({
53
+ connectionId: connection.id,
54
+ threadId,
55
+ state: "offered",
56
+ role: "caller"
57
+ })
58
+ };
59
+ }
60
+ /**
61
+ * Create an answer message with SDP
62
+ */
63
+ createAnswer(agentContext, connection, threadId, parentThreadId, sdp, iceServers) {
64
+ return { message: new AnswerMessage({
65
+ threadId,
66
+ parentThreadId,
67
+ sdp,
68
+ iceServers
69
+ }) };
70
+ }
71
+ /**
72
+ * Create an ICE candidate message
73
+ */
74
+ createIce(threadId, parentThreadId, candidate, endOfCandidates) {
75
+ return new IceMessage({
76
+ threadId,
77
+ parentThreadId,
78
+ candidate,
79
+ endOfCandidates
80
+ });
81
+ }
82
+ /**
83
+ * Create a renegotiate message (for ICE restart, track changes, etc.)
84
+ */
85
+ createRenegotiate(options) {
86
+ return new RenegotiateMessage({
87
+ threadId: options.threadId,
88
+ parentThreadId: options.parentThreadId,
89
+ reason: options.reason,
90
+ iceRestart: options.iceRestart,
91
+ iceServers: options.iceServers,
92
+ policy: options.policy
93
+ });
94
+ }
95
+ /**
96
+ * Create an end call message
97
+ */
98
+ createEnd(threadId, parentThreadId, reason) {
99
+ return new EndMessage({
100
+ threadId,
101
+ parentThreadId,
102
+ reason
103
+ });
104
+ }
105
+ /**
106
+ * Process incoming propose message
107
+ */
108
+ async processPropose(messageContext) {
109
+ const thid = messageContext.message.threadId ?? messageContext.message.id;
110
+ const msg = messageContext.message;
111
+ this.events.emit(messageContext.agentContext, {
112
+ type: WebRTCEvents.IncomingPropose,
113
+ payload: {
114
+ context: messageContext,
115
+ thid,
116
+ pthid: msg.thread?.parentThreadId,
117
+ media: msg.media,
118
+ data: msg.data,
119
+ topology: msg.topology,
120
+ trickle: msg.trickle,
121
+ policy: msg.policy,
122
+ iceServers: msg.iceServers,
123
+ reason: msg.reason
124
+ }
125
+ });
126
+ }
127
+ /**
128
+ * Process incoming offer message
129
+ */
130
+ async processOffer(messageContext) {
131
+ const connection = messageContext.assertReadyConnection();
132
+ const thid = messageContext.message.threadId;
133
+ const msg = messageContext.message;
134
+ const record = new WebRTCCallRecord({
135
+ connectionId: connection.id,
136
+ threadId: thid,
137
+ state: "offered",
138
+ role: "callee"
139
+ });
140
+ await this.repo.save(messageContext.agentContext, record);
141
+ this.events.emit(messageContext.agentContext, {
142
+ type: WebRTCEvents.IncomingOffer,
143
+ payload: {
144
+ context: messageContext,
145
+ thid,
146
+ pthid: msg.thread?.parentThreadId,
147
+ sdp: msg.sdp,
148
+ iceServers: msg.iceServers,
149
+ policy: msg.policy,
150
+ trickle: msg.trickle
151
+ }
152
+ });
153
+ }
154
+ /**
155
+ * Process incoming answer message
156
+ */
157
+ async processAnswer(messageContext) {
158
+ const connection = messageContext.assertReadyConnection();
159
+ const thid = messageContext.message.threadId;
160
+ const msg = messageContext.message;
161
+ const [record] = await this.repo.findByQuery(messageContext.agentContext, {
162
+ connectionId: connection.id,
163
+ threadId: thid
164
+ });
165
+ if (record) {
166
+ record.state = "answered";
167
+ await this.repo.update(messageContext.agentContext, record);
168
+ }
169
+ this.events.emit(messageContext.agentContext, {
170
+ type: WebRTCEvents.IncomingAnswer,
171
+ payload: {
172
+ context: messageContext,
173
+ thid,
174
+ pthid: msg.thread?.parentThreadId,
175
+ sdp: msg.sdp,
176
+ iceServers: msg.iceServers
177
+ }
178
+ });
179
+ }
180
+ /**
181
+ * Process incoming ICE candidate message
182
+ */
183
+ async processIce(messageContext) {
184
+ const thid = messageContext.message.threadId;
185
+ this.events.emit(messageContext.agentContext, {
186
+ type: WebRTCEvents.IncomingIce,
187
+ payload: {
188
+ context: messageContext,
189
+ thid,
190
+ pthid: messageContext.message.thread?.parentThreadId,
191
+ candidate: messageContext.message.candidate ?? {},
192
+ endOfCandidates: messageContext.message.endOfCandidates
193
+ }
194
+ });
195
+ }
196
+ /**
197
+ * Process incoming renegotiate message
198
+ */
199
+ async processRenegotiate(messageContext) {
200
+ const thid = messageContext.message.threadId;
201
+ const msg = messageContext.message;
202
+ this.events.emit(messageContext.agentContext, {
203
+ type: WebRTCEvents.RenegotiateRequested,
204
+ payload: {
205
+ context: messageContext,
206
+ thid,
207
+ pthid: msg.thread?.parentThreadId,
208
+ reason: msg.reason,
209
+ iceRestart: msg.iceRestart,
210
+ iceServers: msg.iceServers,
211
+ policy: msg.policy
212
+ }
213
+ });
214
+ }
215
+ /**
216
+ * Process incoming end call message
217
+ */
218
+ async processEnd(messageContext) {
219
+ const connection = messageContext.assertReadyConnection();
220
+ const thid = messageContext.message.threadId;
221
+ const [record] = await this.repo.findByQuery(messageContext.agentContext, {
222
+ connectionId: connection.id,
223
+ threadId: thid
224
+ });
225
+ if (record) {
226
+ record.state = "ended";
227
+ await this.repo.update(messageContext.agentContext, record);
228
+ }
229
+ this.events.emit(messageContext.agentContext, {
230
+ type: WebRTCEvents.CallEnded,
231
+ payload: {
232
+ context: messageContext,
233
+ thid,
234
+ pthid: messageContext.message.thread?.parentThreadId,
235
+ reason: messageContext.message.reason
236
+ }
237
+ });
238
+ }
239
+ };
240
+ WebRTCService = __decorate([injectable(), __decorateMetadata("design:paramtypes", [typeof (_ref = typeof WebRTCCallRepository !== "undefined" && WebRTCCallRepository) === "function" ? _ref : Object, typeof (_ref2 = typeof EventEmitter !== "undefined" && EventEmitter) === "function" ? _ref2 : Object])], WebRTCService);
241
+
242
+ //#endregion
243
+ export { WebRTCService };
244
+ //# sourceMappingURL=WebRTCService.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WebRTCService.mjs","names":["WebRTCService","repo: WebRTCCallRepository","events: EventEmitter"],"sources":["../../../src/webrtc/services/WebRTCService.ts"],"sourcesContent":["import type { AgentContext } from '@credo-ts/core'\nimport type { DidCommInboundMessageContext, DidCommOutboundMessageContext } from '@credo-ts/didcomm'\nimport type { DidCommConnectionRecord } from '@credo-ts/didcomm'\n\nimport { injectable } from 'tsyringe'\nimport { EventEmitter } from '@credo-ts/core'\n\nimport { AnswerMessage, EndMessage, IceMessage, OfferMessage, ProposeMessage, RenegotiateMessage } from '../messages'\nimport type { IcePolicy, IceServerConfig } from '../messages/OfferMessage'\nimport type { MediaType } from '../messages/ProposeMessage'\nimport type { RenegotiateReason } from '../messages/RenegotiateMessage'\nimport { WebRTCEvents } from '../WebRTCEvents'\nimport { WebRTCCallRecord } from '../repository/WebRTCCallRecord'\nimport { WebRTCCallRepository } from '../repository/WebRTCCallRepository'\n\n@injectable()\nexport class WebRTCService {\n public constructor(private repo: WebRTCCallRepository, private events: EventEmitter) {}\n\n // Outbound creators\n\n /**\n * Create a propose message to initiate a call\n */\n public createPropose(options: {\n threadId?: string\n parentThreadId?: string\n media?: MediaType[]\n data?: boolean\n topology?: 'mesh' | 'sfu'\n trickle?: boolean\n policy?: IcePolicy\n iceServers?: IceServerConfig[]\n reason?: string\n }) {\n const message = new ProposeMessage({\n threadId: options.threadId,\n parentThreadId: options.parentThreadId,\n media: options.media,\n data: options.data,\n topology: options.topology,\n trickle: options.trickle,\n policy: options.policy,\n iceServers: options.iceServers,\n reason: options.reason,\n })\n return { message }\n }\n\n /**\n * Create an offer message with SDP\n */\n public createOffer(\n agentContext: AgentContext,\n connection: DidCommConnectionRecord,\n threadId: string,\n parentThreadId: string | undefined,\n sdp: string,\n iceServers?: IceServerConfig[],\n policy?: IcePolicy,\n trickle?: boolean\n ) {\n const message = new OfferMessage({ threadId, parentThreadId, sdp, iceServers, policy, trickle })\n const record = new WebRTCCallRecord({ connectionId: connection.id, threadId, state: 'offered', role: 'caller' })\n return { message, record }\n }\n\n /**\n * Create an answer message with SDP\n */\n public createAnswer(\n agentContext: AgentContext,\n connection: DidCommConnectionRecord,\n threadId: string,\n parentThreadId: string | undefined,\n sdp: string,\n iceServers?: IceServerConfig[]\n ) {\n const message = new AnswerMessage({ threadId, parentThreadId, sdp, iceServers })\n return { message }\n }\n\n /**\n * Create an ICE candidate message\n */\n public createIce(\n threadId: string,\n parentThreadId: string | undefined,\n candidate: Record<string, unknown> | undefined,\n endOfCandidates?: boolean\n ) {\n return new IceMessage({ threadId, parentThreadId, candidate, endOfCandidates })\n }\n\n /**\n * Create a renegotiate message (for ICE restart, track changes, etc.)\n */\n public createRenegotiate(options: {\n threadId: string\n parentThreadId?: string\n reason: RenegotiateReason | string\n iceRestart?: boolean\n iceServers?: IceServerConfig[]\n policy?: IcePolicy\n }) {\n return new RenegotiateMessage({\n threadId: options.threadId,\n parentThreadId: options.parentThreadId,\n reason: options.reason,\n iceRestart: options.iceRestart,\n iceServers: options.iceServers,\n policy: options.policy,\n })\n }\n\n /**\n * Create an end call message\n */\n public createEnd(threadId: string, parentThreadId: string | undefined, reason?: string) {\n return new EndMessage({ threadId, parentThreadId, reason })\n }\n\n // Inbound processors\n\n /**\n * Process incoming propose message\n */\n public async processPropose(messageContext: DidCommInboundMessageContext<ProposeMessage>): Promise<void> {\n const thid = messageContext.message.threadId ?? messageContext.message.id\n const msg = messageContext.message\n\n this.events.emit(messageContext.agentContext, {\n type: WebRTCEvents.IncomingPropose,\n payload: {\n context: messageContext,\n thid,\n pthid: msg.thread?.parentThreadId,\n media: msg.media,\n data: msg.data,\n topology: msg.topology,\n trickle: msg.trickle,\n policy: msg.policy,\n iceServers: msg.iceServers,\n reason: msg.reason,\n },\n } as any)\n return\n }\n\n /**\n * Process incoming offer message\n */\n public async processOffer(messageContext: DidCommInboundMessageContext<OfferMessage>): Promise<void> {\n const connection = messageContext.assertReadyConnection()\n const thid = messageContext.message.threadId\n const msg = messageContext.message\n\n const record = new WebRTCCallRecord({\n connectionId: connection.id,\n threadId: thid,\n state: 'offered',\n role: 'callee',\n })\n await this.repo.save(messageContext.agentContext, record)\n\n this.events.emit(messageContext.agentContext, {\n type: WebRTCEvents.IncomingOffer,\n payload: {\n context: messageContext,\n thid,\n pthid: msg.thread?.parentThreadId,\n sdp: msg.sdp,\n iceServers: msg.iceServers,\n policy: msg.policy,\n trickle: msg.trickle,\n },\n } as any)\n return\n }\n\n /**\n * Process incoming answer message\n */\n public async processAnswer(messageContext: DidCommInboundMessageContext<AnswerMessage>): Promise<void> {\n const connection = messageContext.assertReadyConnection()\n const thid = messageContext.message.threadId\n const msg = messageContext.message\n\n const [record] = await this.repo.findByQuery(messageContext.agentContext, {\n connectionId: connection.id,\n threadId: thid,\n })\n if (record) {\n record.state = 'answered'\n await this.repo.update(messageContext.agentContext, record)\n }\n\n this.events.emit(messageContext.agentContext, {\n type: WebRTCEvents.IncomingAnswer,\n payload: {\n context: messageContext,\n thid,\n pthid: msg.thread?.parentThreadId,\n sdp: msg.sdp,\n iceServers: msg.iceServers,\n },\n } as any)\n return\n }\n\n /**\n * Process incoming ICE candidate message\n */\n public async processIce(messageContext: DidCommInboundMessageContext<IceMessage>): Promise<void> {\n const thid = messageContext.message.threadId\n this.events.emit(messageContext.agentContext, {\n type: WebRTCEvents.IncomingIce,\n payload: {\n context: messageContext,\n thid,\n pthid: messageContext.message.thread?.parentThreadId,\n candidate: messageContext.message.candidate ?? {},\n endOfCandidates: messageContext.message.endOfCandidates,\n },\n } as any)\n return\n }\n\n /**\n * Process incoming renegotiate message\n */\n public async processRenegotiate(messageContext: DidCommInboundMessageContext<RenegotiateMessage>): Promise<void> {\n const thid = messageContext.message.threadId\n const msg = messageContext.message\n\n this.events.emit(messageContext.agentContext, {\n type: WebRTCEvents.RenegotiateRequested,\n payload: {\n context: messageContext,\n thid,\n pthid: msg.thread?.parentThreadId,\n reason: msg.reason,\n iceRestart: msg.iceRestart,\n iceServers: msg.iceServers,\n policy: msg.policy,\n },\n } as any)\n return\n }\n\n /**\n * Process incoming end call message\n */\n public async processEnd(messageContext: DidCommInboundMessageContext<EndMessage>): Promise<void> {\n const connection = messageContext.assertReadyConnection()\n const thid = messageContext.message.threadId\n const [record] = await this.repo.findByQuery(messageContext.agentContext, {\n connectionId: connection.id,\n threadId: thid,\n })\n if (record) {\n record.state = 'ended'\n await this.repo.update(messageContext.agentContext, record)\n }\n this.events.emit(messageContext.agentContext, {\n type: WebRTCEvents.CallEnded,\n payload: {\n context: messageContext,\n thid,\n pthid: messageContext.message.thread?.parentThreadId,\n reason: messageContext.message.reason,\n },\n } as any)\n return\n }\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,28 +1,32 @@
1
1
  {
2
2
  "name": "@ajna-inc/webrtc",
3
- "version": "0.2.1",
4
- "private": false,
5
- "main": "build/index.js",
6
- "types": "build/index.d.ts",
3
+ "exports": {
4
+ ".": "./build/index.mjs",
5
+ "./package.json": "./package.json"
6
+ },
7
+ "version": "0.6.1",
7
8
  "files": [
8
- "build"
9
+ "build",
10
+ ".npmvc"
9
11
  ],
12
+ "license": "Apache-2.0",
10
13
  "publishConfig": {
11
14
  "access": "public"
12
15
  },
13
16
  "dependencies": {
14
- "class-transformer": "^0.5.1",
15
- "class-validator": "^0.14.0",
16
- "tsyringe": "^4.8.0"
17
- },
18
- "peerDependencies": {
19
- "@credo-ts/core": "^0.5.17"
17
+ "class-transformer": "0.5.1",
18
+ "class-validator": "^0.14.1",
19
+ "@credo-ts/core": "0.6.1",
20
+ "@credo-ts/didcomm": "0.6.1"
20
21
  },
21
22
  "devDependencies": {
22
- "@credo-ts/core": "^0.5.17"
23
+ "reflect-metadata": "0.2.2",
24
+ "typescript": "~5.9.3"
23
25
  },
26
+ "publisher": "did:key:z6MktNpDRgzA26pH13MxEPU4nmB6BwxxgCajhGHERPCrPGpD",
24
27
  "scripts": {
25
- "build": "tsc -p tsconfig.build.json",
26
- "clean": "rimraf build"
27
- }
28
+ "build": "tsdown --config-loader unconfig"
29
+ },
30
+ "types": "./build/index.d.mts",
31
+ "module": "./build/index.mjs"
28
32
  }
package/README.md DELETED
@@ -1,222 +0,0 @@
1
- # @ajna-inc/webrtc
2
-
3
- DIDComm v2 signaling protocol for WebRTC P2P calls with full NAT/firewall traversal support.
4
-
5
- - PIURI: `https://didcomm.org/webrtc/1.0`
6
- - Messages: `propose`, `offer`, `answer`, `ice`, `renegotiate`, `end`
7
- - Advertises support via Discover Features; works with mediators and message pickup.
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
-
17
- ## Install
18
-
19
- This package is part of the monorepo. Add the module to your Agent options:
20
-
21
- ```ts
22
- import { WebRTCModule } from '@ajna-inc/webrtc'
23
-
24
- const agent = new Agent({
25
- config: { /* ... */ },
26
- dependencies: agentDependencies,
27
- modules: {
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
- }),
62
- },
63
- })
64
- ```
65
-
66
- ## Frontend usage (browser)
67
-
68
- Below is a setup for P2P WebRTC using Credo TS for signaling.
69
-
70
- ```ts
71
- // Get configured ICE servers from module
72
- const iceServers = agent.modules.webrtc.getDefaultIceServers()
73
-
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
-
82
- agent.events.on('WebRTCEvents.IncomingOffer', async ({ payload }) => {
83
- const { thid, sdp, iceServers, policy, context } = payload
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 })
93
- const answer = await pc.createAnswer()
94
- await pc.setLocalDescription(answer)
95
-
96
- await agent.modules.webrtc.acceptCall({
97
- connectionId: context.connection!.id,
98
- threadId: thid,
99
- sdp: answer.sdp!,
100
- })
101
- })
102
-
103
- agent.events.on('WebRTCEvents.IncomingAnswer', async ({ payload }) => {
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
109
- await pc.setRemoteDescription({ type: 'answer', sdp })
110
- })
111
-
112
- agent.events.on('WebRTCEvents.IncomingIce', async ({ payload }) => {
113
- const { thid, candidate, endOfCandidates } = payload
114
- const pc = peers.get(thid)
115
- if (!pc) return
116
- if (endOfCandidates) await pc.addIceCandidate(null)
117
- else await pc.addIceCandidate(candidate as RTCIceCandidateInit)
118
- })
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
-
134
- // Start call (caller)
135
- async function startCall(connectionId: string, localStream: MediaStream) {
136
- const thid = crypto.randomUUID()
137
-
138
- // Use module's default ICE servers
139
- const iceServers = agent.modules.webrtc.getDefaultIceServers()
140
-
141
- const pc = new RTCPeerConnection({ iceServers })
142
- peers.set(thid, pc)
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
-
152
- // Render remote stream
153
- pc.ontrack = e => (remoteVideo.srcObject = e.streams[0])
154
-
155
- // Send ICE via DIDComm
156
- pc.onicecandidate = e => agent.modules.webrtc.sendIce({
157
- connectionId,
158
- threadId: thid,
159
- candidate: e.candidate ?? undefined,
160
- endOfCandidates: e.candidate == null,
161
- })
162
-
163
- // Add local tracks
164
- for (const track of localStream.getTracks()) pc.addTrack(track, localStream)
165
-
166
- const offer = await pc.createOffer({ offerToReceiveVideo: true, offerToReceiveAudio: true })
167
- await pc.setLocalDescription(offer)
168
-
169
- // Start call - ICE servers are automatically included from module config
170
- await agent.modules.webrtc.startCall({
171
- connectionId,
172
- threadId: thid,
173
- sdp: offer.sdp!,
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' }],
186
- })
187
- }
188
- ```
189
-
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
-
218
- - This module moves only signaling over DIDComm; media flows via WebRTC/DTLS-SRTP.
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).
221
- - Works with mediators and message pickup (offline delivery), as with any DIDComm message.
222
-
package/build/index.d.ts DELETED
@@ -1,8 +0,0 @@
1
- export { WebRTCModule, WebRTCModuleConfigToken } from './webrtc/WebRTCModule';
2
- export type { WebRTCModuleConfig, WebRTCIceServerConfig } from './webrtc/WebRTCModule';
3
- export { WebRTCApi } from './webrtc/WebRTCApi';
4
- export { WebRTCEvents, type IceServerEventConfig, type IncomingProposeEvent, type IncomingOfferEvent, type IncomingAnswerEvent, type IncomingIceEvent, type RenegotiateRequestedEvent, type CallEndedEvent, } from './webrtc/WebRTCEvents';
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 DELETED
@@ -1,29 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
- };
16
- Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.WebRTCEvents = exports.WebRTCApi = exports.WebRTCModuleConfigToken = exports.WebRTCModule = void 0;
18
- // Module and API
19
- var WebRTCModule_1 = require("./webrtc/WebRTCModule");
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; } });
22
- var WebRTCApi_1 = require("./webrtc/WebRTCApi");
23
- Object.defineProperty(exports, "WebRTCApi", { enumerable: true, get: function () { return WebRTCApi_1.WebRTCApi; } });
24
- // Events
25
- var WebRTCEvents_1 = require("./webrtc/WebRTCEvents");
26
- Object.defineProperty(exports, "WebRTCEvents", { enumerable: true, get: function () { return WebRTCEvents_1.WebRTCEvents; } });
27
- // Messages
28
- __exportStar(require("./webrtc/messages"), exports);
29
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
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"}