@japofc/baileys 2.1.0

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 (342) hide show
  1. package/NOTICE.md +111 -0
  2. package/README.md +1254 -0
  3. package/WAProto/index.d.ts +9 -0
  4. package/WAProto/index.js +142276 -0
  5. package/engine-requirements.js +13 -0
  6. package/lib/Builders/A2UI.d.ts +242 -0
  7. package/lib/Builders/A2UI.js +308 -0
  8. package/lib/Builders/AIRich.d.ts +105 -0
  9. package/lib/Builders/AIRich.js +2286 -0
  10. package/lib/Builders/Button.d.ts +103 -0
  11. package/lib/Builders/Button.js +883 -0
  12. package/lib/Builders/ButtonV2.d.ts +28 -0
  13. package/lib/Builders/ButtonV2.js +144 -0
  14. package/lib/Builders/ButtonV3.d.ts +25 -0
  15. package/lib/Builders/ButtonV3.js +184 -0
  16. package/lib/Builders/Carousel.d.ts +22 -0
  17. package/lib/Builders/Carousel.js +111 -0
  18. package/lib/Builders/JapBaileys.d.ts +34 -0
  19. package/lib/Builders/JapBaileys.js +108 -0
  20. package/lib/Builders/Poll.d.ts +25 -0
  21. package/lib/Builders/Poll.js +128 -0
  22. package/lib/Builders/index.d.ts +17 -0
  23. package/lib/Builders/index.js +11 -0
  24. package/lib/Builders/shared.d.ts +67 -0
  25. package/lib/Builders/shared.js +652 -0
  26. package/lib/Defaults/index.d.ts +154 -0
  27. package/lib/Defaults/index.js +178 -0
  28. package/lib/Framework/Bot.d.ts +61 -0
  29. package/lib/Framework/Bot.js +248 -0
  30. package/lib/Framework/Context.d.ts +21 -0
  31. package/lib/Framework/Context.js +89 -0
  32. package/lib/Framework/MediaManager.d.ts +17 -0
  33. package/lib/Framework/MediaManager.js +151 -0
  34. package/lib/Framework/SessionManager.d.ts +13 -0
  35. package/lib/Framework/SessionManager.js +33 -0
  36. package/lib/Framework/StatsManager.d.ts +26 -0
  37. package/lib/Framework/StatsManager.js +119 -0
  38. package/lib/Framework/Store/SQLiteStore.d.ts +11 -0
  39. package/lib/Framework/Store/SQLiteStore.js +73 -0
  40. package/lib/Framework/index.d.ts +9 -0
  41. package/lib/Framework/index.js +10 -0
  42. package/lib/Signal/Group/ciphertext-message.d.ts +9 -0
  43. package/lib/Signal/Group/ciphertext-message.js +11 -0
  44. package/lib/Signal/Group/group-session-builder.d.ts +7 -0
  45. package/lib/Signal/Group/group-session-builder.js +29 -0
  46. package/lib/Signal/Group/group_cipher.d.ts +10 -0
  47. package/lib/Signal/Group/group_cipher.js +81 -0
  48. package/lib/Signal/Group/index.d.ts +11 -0
  49. package/lib/Signal/Group/index.js +11 -0
  50. package/lib/Signal/Group/keyhelper.d.ts +6 -0
  51. package/lib/Signal/Group/keyhelper.js +17 -0
  52. package/lib/Signal/Group/sender-chain-key.d.ts +13 -0
  53. package/lib/Signal/Group/sender-chain-key.js +25 -0
  54. package/lib/Signal/Group/sender-key-distribution-message.d.ts +16 -0
  55. package/lib/Signal/Group/sender-key-distribution-message.js +62 -0
  56. package/lib/Signal/Group/sender-key-message.d.ts +18 -0
  57. package/lib/Signal/Group/sender-key-message.js +65 -0
  58. package/lib/Signal/Group/sender-key-name.d.ts +11 -0
  59. package/lib/Signal/Group/sender-key-name.js +47 -0
  60. package/lib/Signal/Group/sender-key-record.d.ts +12 -0
  61. package/lib/Signal/Group/sender-key-record.js +40 -0
  62. package/lib/Signal/Group/sender-key-state.d.ts +16 -0
  63. package/lib/Signal/Group/sender-key-state.js +83 -0
  64. package/lib/Signal/Group/sender-message-key.d.ts +11 -0
  65. package/lib/Signal/Group/sender-message-key.js +25 -0
  66. package/lib/Signal/libsignal.d.ts +54 -0
  67. package/lib/Signal/libsignal.js +430 -0
  68. package/lib/Signal/lid-mapping.d.ts +20 -0
  69. package/lib/Signal/lid-mapping.js +276 -0
  70. package/lib/Socket/Client/index.d.ts +2 -0
  71. package/lib/Socket/Client/index.js +2 -0
  72. package/lib/Socket/Client/types.d.ts +5 -0
  73. package/lib/Socket/Client/types.js +10 -0
  74. package/lib/Socket/Client/websocket.d.ts +12 -0
  75. package/lib/Socket/Client/websocket.js +53 -0
  76. package/lib/Socket/business.d.ts +395 -0
  77. package/lib/Socket/business.js +379 -0
  78. package/lib/Socket/chats.d.ts +136 -0
  79. package/lib/Socket/chats.js +1327 -0
  80. package/lib/Socket/communities.d.ts +562 -0
  81. package/lib/Socket/communities.js +439 -0
  82. package/lib/Socket/dugong.d.ts +117 -0
  83. package/lib/Socket/dugong.js +798 -0
  84. package/lib/Socket/groups.d.ts +285 -0
  85. package/lib/Socket/groups.js +354 -0
  86. package/lib/Socket/index.d.ts +585 -0
  87. package/lib/Socket/index.js +52 -0
  88. package/lib/Socket/messages-recv.d.ts +333 -0
  89. package/lib/Socket/messages-recv.js +1781 -0
  90. package/lib/Socket/messages-send.d.ts +353 -0
  91. package/lib/Socket/messages-send.js +1524 -0
  92. package/lib/Socket/mex.d.ts +1 -0
  93. package/lib/Socket/mex.js +41 -0
  94. package/lib/Socket/newsletter.d.ts +286 -0
  95. package/lib/Socket/newsletter.js +364 -0
  96. package/lib/Socket/socket.d.ts +60 -0
  97. package/lib/Socket/socket.js +1012 -0
  98. package/lib/Socket/username.d.ts +82 -0
  99. package/lib/Socket/username.js +159 -0
  100. package/lib/Store/index.d.ts +3 -0
  101. package/lib/Store/index.js +3 -0
  102. package/lib/Store/make-in-memory-store.d.ts +62 -0
  103. package/lib/Store/make-in-memory-store.js +428 -0
  104. package/lib/Store/make-ordered-dictionary.d.ts +12 -0
  105. package/lib/Store/make-ordered-dictionary.js +78 -0
  106. package/lib/Store/object-repository.d.ts +10 -0
  107. package/lib/Store/object-repository.js +23 -0
  108. package/lib/Types/Auth.d.ts +117 -0
  109. package/lib/Types/Auth.js +1 -0
  110. package/lib/Types/Bussines.d.ts +25 -0
  111. package/lib/Types/Call.d.ts +15 -0
  112. package/lib/Types/Call.js +1 -0
  113. package/lib/Types/Chat.d.ts +124 -0
  114. package/lib/Types/Chat.js +7 -0
  115. package/lib/Types/Contact.d.ts +26 -0
  116. package/lib/Types/Contact.js +1 -0
  117. package/lib/Types/Events.d.ts +256 -0
  118. package/lib/Types/Events.js +1 -0
  119. package/lib/Types/GroupMetadata.d.ts +71 -0
  120. package/lib/Types/GroupMetadata.js +1 -0
  121. package/lib/Types/Label.d.ts +5 -0
  122. package/lib/Types/Label.js +24 -0
  123. package/lib/Types/LabelAssociation.d.ts +6 -0
  124. package/lib/Types/LabelAssociation.js +6 -0
  125. package/lib/Types/Message.d.ts +62 -0
  126. package/lib/Types/Message.js +17 -0
  127. package/lib/Types/Mex.d.ts +2 -0
  128. package/lib/Types/Mex.js +38 -0
  129. package/lib/Types/Product.d.ts +79 -0
  130. package/lib/Types/Product.js +1 -0
  131. package/lib/Types/RichType.d.ts +2 -0
  132. package/lib/Types/RichType.js +22 -0
  133. package/lib/Types/Signal.d.ts +87 -0
  134. package/lib/Types/Signal.js +1 -0
  135. package/lib/Types/Socket.d.ts +138 -0
  136. package/lib/Types/Socket.js +1 -0
  137. package/lib/Types/State.d.ts +8 -0
  138. package/lib/Types/State.js +55 -0
  139. package/lib/Types/USync.d.ts +26 -0
  140. package/lib/Types/index.d.ts +68 -0
  141. package/lib/Types/index.js +27 -0
  142. package/lib/Utils/MessageBuilder.d.ts +2 -0
  143. package/lib/Utils/MessageBuilder.js +2 -0
  144. package/lib/Utils/PersistentStore.d.ts +60 -0
  145. package/lib/Utils/PersistentStore.js +592 -0
  146. package/lib/Utils/anti-delete.d.ts +74 -0
  147. package/lib/Utils/anti-delete.js +221 -0
  148. package/lib/Utils/auth-secure.d.ts +86 -0
  149. package/lib/Utils/auth-secure.js +764 -0
  150. package/lib/Utils/auth-utils.d.ts +57 -0
  151. package/lib/Utils/auth-utils.js +306 -0
  152. package/lib/Utils/auto-reply.d.ts +47 -0
  153. package/lib/Utils/auto-reply.js +157 -0
  154. package/lib/Utils/baileys-event-stream.d.ts +8 -0
  155. package/lib/Utils/baileys-event-stream.js +62 -0
  156. package/lib/Utils/browser-utils.d.ts +8 -0
  157. package/lib/Utils/browser-utils.js +27 -0
  158. package/lib/Utils/business.d.ts +49 -0
  159. package/lib/Utils/business.js +239 -0
  160. package/lib/Utils/button-helper-utils.d.ts +53 -0
  161. package/lib/Utils/button-helper-utils.js +312 -0
  162. package/lib/Utils/button-sender.d.ts +54 -0
  163. package/lib/Utils/button-sender.js +822 -0
  164. package/lib/Utils/chat-control.d.ts +159 -0
  165. package/lib/Utils/chat-control.js +230 -0
  166. package/lib/Utils/chat-history-helpers.d.ts +21 -0
  167. package/lib/Utils/chat-history-helpers.js +70 -0
  168. package/lib/Utils/chat-utils.d.ts +407 -0
  169. package/lib/Utils/chat-utils.js +885 -0
  170. package/lib/Utils/companion-reg-client-utils.d.ts +4 -0
  171. package/lib/Utils/companion-reg-client-utils.js +39 -0
  172. package/lib/Utils/crypto.d.ts +41 -0
  173. package/lib/Utils/crypto.js +147 -0
  174. package/lib/Utils/decode-wa-message.d.ts +83 -0
  175. package/lib/Utils/decode-wa-message.js +316 -0
  176. package/lib/Utils/event-buffer.d.ts +12 -0
  177. package/lib/Utils/event-buffer.js +635 -0
  178. package/lib/Utils/generics.d.ts +69 -0
  179. package/lib/Utils/generics.js +438 -0
  180. package/lib/Utils/history-share.d.ts +11 -0
  181. package/lib/Utils/history-share.js +70 -0
  182. package/lib/Utils/history.d.ts +90 -0
  183. package/lib/Utils/history.js +146 -0
  184. package/lib/Utils/humanizer.d.ts +12 -0
  185. package/lib/Utils/humanizer.js +73 -0
  186. package/lib/Utils/identity-change-handler.d.ts +13 -0
  187. package/lib/Utils/identity-change-handler.js +49 -0
  188. package/lib/Utils/index.d.ts +57 -0
  189. package/lib/Utils/index.js +56 -0
  190. package/lib/Utils/jid-tools.d.ts +6 -0
  191. package/lib/Utils/jid-tools.js +77 -0
  192. package/lib/Utils/link-preview.d.ts +12 -0
  193. package/lib/Utils/link-preview.js +84 -0
  194. package/lib/Utils/logger.d.ts +4 -0
  195. package/lib/Utils/logger.js +2 -0
  196. package/lib/Utils/lt-hash.d.ts +12 -0
  197. package/lib/Utils/lt-hash.js +26 -0
  198. package/lib/Utils/make-mutex.d.ts +6 -0
  199. package/lib/Utils/make-mutex.js +32 -0
  200. package/lib/Utils/media-messages.d.ts +18 -0
  201. package/lib/Utils/media-messages.js +70 -0
  202. package/lib/Utils/media-set.d.ts +13 -0
  203. package/lib/Utils/media-set.js +171 -0
  204. package/lib/Utils/message-kind.d.ts +32 -0
  205. package/lib/Utils/message-kind.js +136 -0
  206. package/lib/Utils/message-retry-manager.d.ts +79 -0
  207. package/lib/Utils/message-retry-manager.js +264 -0
  208. package/lib/Utils/message-search.d.ts +44 -0
  209. package/lib/Utils/message-search.js +188 -0
  210. package/lib/Utils/messages-media.d.ts +135 -0
  211. package/lib/Utils/messages-media.js +868 -0
  212. package/lib/Utils/messages.d.ts +44 -0
  213. package/lib/Utils/messages.js +2326 -0
  214. package/lib/Utils/meta-ai.d.ts +13 -0
  215. package/lib/Utils/meta-ai.js +74 -0
  216. package/lib/Utils/mini-app.d.ts +35 -0
  217. package/lib/Utils/mini-app.js +213 -0
  218. package/lib/Utils/noise-handler.d.ts +20 -0
  219. package/lib/Utils/noise-handler.js +200 -0
  220. package/lib/Utils/offline-node-processor.d.ts +9 -0
  221. package/lib/Utils/offline-node-processor.js +39 -0
  222. package/lib/Utils/past-participants.d.ts +14 -0
  223. package/lib/Utils/past-participants.js +40 -0
  224. package/lib/Utils/pre-key-manager.d.ts +25 -0
  225. package/lib/Utils/pre-key-manager.js +105 -0
  226. package/lib/Utils/process-message.d.ts +82 -0
  227. package/lib/Utils/process-message.js +808 -0
  228. package/lib/Utils/qr-render.d.ts +59 -0
  229. package/lib/Utils/qr-render.js +179 -0
  230. package/lib/Utils/qrcodegen.d.ts +79 -0
  231. package/lib/Utils/qrcodegen.js +848 -0
  232. package/lib/Utils/reporting-utils.d.ts +12 -0
  233. package/lib/Utils/reporting-utils.js +257 -0
  234. package/lib/Utils/rich-message-utils.d.ts +48 -0
  235. package/lib/Utils/rich-message-utils.js +444 -0
  236. package/lib/Utils/router.d.ts +37 -0
  237. package/lib/Utils/router.js +165 -0
  238. package/lib/Utils/scheduled-posts.d.ts +30 -0
  239. package/lib/Utils/scheduled-posts.js +110 -0
  240. package/lib/Utils/scheduling.d.ts +42 -0
  241. package/lib/Utils/scheduling.js +139 -0
  242. package/lib/Utils/signal.d.ts +82 -0
  243. package/lib/Utils/signal.js +200 -0
  244. package/lib/Utils/stanza-ack.d.ts +16 -0
  245. package/lib/Utils/stanza-ack.js +37 -0
  246. package/lib/Utils/status.d.ts +50 -0
  247. package/lib/Utils/status.js +107 -0
  248. package/lib/Utils/stickerpack.d.ts +51 -0
  249. package/lib/Utils/stickerpack.js +274 -0
  250. package/lib/Utils/sync-action-utils.d.ts +2 -0
  251. package/lib/Utils/sync-action-utils.js +48 -0
  252. package/lib/Utils/tag.d.ts +12 -0
  253. package/lib/Utils/tag.js +44 -0
  254. package/lib/Utils/tc-token-utils.d.ts +29 -0
  255. package/lib/Utils/tc-token-utils.js +162 -0
  256. package/lib/Utils/templates.d.ts +76 -0
  257. package/lib/Utils/templates.js +150 -0
  258. package/lib/Utils/transcribe.d.ts +12 -0
  259. package/lib/Utils/transcribe.js +107 -0
  260. package/lib/Utils/use-cache-manager-auth-state.d.ts +13 -0
  261. package/lib/Utils/use-cache-manager-auth-state.js +81 -0
  262. package/lib/Utils/use-multi-file-auth-state.d.ts +10 -0
  263. package/lib/Utils/use-multi-file-auth-state.js +166 -0
  264. package/lib/Utils/use-single-file-auth-state.d.ts +10 -0
  265. package/lib/Utils/use-single-file-auth-state.js +113 -0
  266. package/lib/Utils/use-sqlite-auth-state.d.ts +11 -0
  267. package/lib/Utils/use-sqlite-auth-state.js +169 -0
  268. package/lib/Utils/validate-connection.d.ts +42 -0
  269. package/lib/Utils/validate-connection.js +198 -0
  270. package/lib/Utils/vcard.d.ts +58 -0
  271. package/lib/Utils/vcard.js +104 -0
  272. package/lib/Utils/voice-note.d.ts +15 -0
  273. package/lib/Utils/voice-note.js +63 -0
  274. package/lib/VoIP/audio-feeder.d.ts +18 -0
  275. package/lib/VoIP/audio-feeder.js +160 -0
  276. package/lib/VoIP/call-recorder.d.ts +13 -0
  277. package/lib/VoIP/call-recorder.js +73 -0
  278. package/lib/VoIP/index.d.ts +86 -0
  279. package/lib/VoIP/index.js +611 -0
  280. package/lib/VoIP/relay-transport.d.ts +43 -0
  281. package/lib/VoIP/relay-transport.js +563 -0
  282. package/lib/VoIP/signaling.d.ts +26 -0
  283. package/lib/VoIP/signaling.js +662 -0
  284. package/lib/VoIP/types.d.ts +69 -0
  285. package/lib/VoIP/types.js +17 -0
  286. package/lib/VoIP/wasm-engine.d.ts +120 -0
  287. package/lib/VoIP/wasm-engine.js +1358 -0
  288. package/lib/VoIP/worker-bootstrap.d.ts +4 -0
  289. package/lib/VoIP/worker-bootstrap.js +1046 -0
  290. package/lib/WABinary/constants.d.ts +61 -0
  291. package/lib/WABinary/constants.js +1466 -0
  292. package/lib/WABinary/decode.d.ts +9 -0
  293. package/lib/WABinary/decode.js +261 -0
  294. package/lib/WABinary/encode.d.ts +2 -0
  295. package/lib/WABinary/encode.js +219 -0
  296. package/lib/WABinary/generic-utils.d.ts +74 -0
  297. package/lib/WABinary/generic-utils.js +276 -0
  298. package/lib/WABinary/index.d.ts +5 -0
  299. package/lib/WABinary/index.js +5 -0
  300. package/lib/WABinary/jid-utils.d.ts +28 -0
  301. package/lib/WABinary/jid-utils.js +95 -0
  302. package/lib/WABinary/types.d.ts +19 -0
  303. package/lib/WABinary/types.js +1 -0
  304. package/lib/WAM/BinaryInfo.d.ts +7 -0
  305. package/lib/WAM/BinaryInfo.js +9 -0
  306. package/lib/WAM/constants.d.ts +34926 -0
  307. package/lib/WAM/constants.js +22852 -0
  308. package/lib/WAM/encode.d.ts +1 -0
  309. package/lib/WAM/encode.js +149 -0
  310. package/lib/WAM/index.d.ts +3 -0
  311. package/lib/WAM/index.js +3 -0
  312. package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +36 -0
  313. package/lib/WAUSync/Protocols/USyncContactProtocol.js +51 -0
  314. package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +29 -0
  315. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +62 -0
  316. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +12 -0
  317. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +26 -0
  318. package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +12 -0
  319. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +37 -0
  320. package/lib/WAUSync/Protocols/USyncUsernameProtocol.d.ts +9 -0
  321. package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +24 -0
  322. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts +38 -0
  323. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +50 -0
  324. package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts +14 -0
  325. package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +28 -0
  326. package/lib/WAUSync/Protocols/index.d.ts +7 -0
  327. package/lib/WAUSync/Protocols/index.js +7 -0
  328. package/lib/WAUSync/USyncQuery.d.ts +20 -0
  329. package/lib/WAUSync/USyncQuery.js +121 -0
  330. package/lib/WAUSync/USyncUser.d.ts +16 -0
  331. package/lib/WAUSync/USyncUser.js +30 -0
  332. package/lib/WAUSync/index.d.ts +3 -0
  333. package/lib/WAUSync/index.js +3 -0
  334. package/lib/assets/wasm/loader.d.ts +5 -0
  335. package/lib/assets/wasm/loader.js +5 -0
  336. package/lib/assets/wasm/whatsapp.wasm +0 -0
  337. package/lib/assets/wasm/worker-modules.d.ts +5 -0
  338. package/lib/assets/wasm/worker-modules.js +273 -0
  339. package/lib/index.d.ts +18 -0
  340. package/lib/index.js +23 -0
  341. package/package.json +180 -0
  342. package/postinstall-banner.js +82 -0
@@ -0,0 +1,563 @@
1
+ /**
2
+ * Relay transport.
3
+ *
4
+ * Tunnels UDP traffic to WhatsApp's edge relay servers via WebRTC data
5
+ * channels (using `@roamhq/wrtc`). Mirrors the browser client's behavior:
6
+ * pre-negotiated SCTP, custom DTLS fingerprint, ICE restart on idle.
7
+ *
8
+ * @author J.AP
9
+ */
10
+ import { appendFileSync } from "node:fs";
11
+ const RELAY_PROTO_UDP = 0;
12
+ const FAUX_WEB_CLIENT_RELAY_PORT = 3478;
13
+ const TRUE_WEB_CLIENT_RELAY_PORT = 3480;
14
+ const CONNECTION_TIMEOUT_MS = 20_000;
15
+ const ICE_RESTART_IDLE_THRESHOLD_MS = 10_000;
16
+ const ICE_RTT_POLL_MS = 1_000;
17
+ const MAX_BUFFER_SIZE = 256 * 1024;
18
+ const RELAY_PACKET_LOG_PATH = process.env.CALL_DUMP_RELAY_PACKETS_PATH ?? "";
19
+ const DISABLE_IPV6 = process.env.CALL_DISABLE_IPV6 !== "0";
20
+ const RELAY_PORT_MODE = process.env.CALL_RELAY_PORT_MODE === "web" ? "web" : "original";
21
+ const USE_ORIGINAL_RELAY_PORTS = RELAY_PORT_MODE === "original";
22
+ const RELAY_DTLS_FINGERPRINT = "F9:CA:0C:98:A3:CC:71:D6:42:CE:5A:E2:53:D2:15:20:D3:1B:BA:D8:57:A4:F0:AF:BE:0B:FB:F3:6B:0C:A0:68";
23
+ const getConnectionIdentifier = (ip, port) => ip.includes(":") ? `[${ip}]:${port}` : `${ip}:${port}`;
24
+ const createEmptyStats = () => ({
25
+ sentPackets: 0,
26
+ receivedPackets: 0,
27
+ sentBytes: 0,
28
+ receivedBytes: 0,
29
+ droppedPackets: 0,
30
+ openConnections: 0,
31
+ });
32
+ const getRelayLookupId = (ip, port) => getConnectionIdentifier(ip, port === TRUE_WEB_CLIENT_RELAY_PORT ? TRUE_WEB_CLIENT_RELAY_PORT : port);
33
+ const getRtcConnectPort = (info) => info.ip === "157.240.24.133" ? FAUX_WEB_CLIENT_RELAY_PORT : info.port;
34
+ const getVoipStackPort = (info) => {
35
+ if (USE_ORIGINAL_RELAY_PORTS)
36
+ return info.originalPort || info.port;
37
+ const sourcePort = info.originalPort || info.port;
38
+ return sourcePort === TRUE_WEB_CLIENT_RELAY_PORT
39
+ ? TRUE_WEB_CLIENT_RELAY_PORT
40
+ : FAUX_WEB_CLIENT_RELAY_PORT;
41
+ };
42
+ const bufferPacket = (connection, packet) => {
43
+ if (packet.byteLength > MAX_BUFFER_SIZE) {
44
+ connection.stats.droppedPackets += 1;
45
+ return false;
46
+ }
47
+ while (connection.packetBuffer.length > 0 &&
48
+ connection.bufferedBytes + packet.byteLength > MAX_BUFFER_SIZE) {
49
+ const dropped = connection.packetBuffer.shift();
50
+ if (dropped) {
51
+ connection.bufferedBytes -= dropped.byteLength;
52
+ connection.stats.droppedPackets += 1;
53
+ }
54
+ }
55
+ connection.packetBuffer.push(packet);
56
+ connection.bufferedBytes += packet.byteLength;
57
+ return true;
58
+ };
59
+ const shiftPacket = (connection) => {
60
+ const packet = connection.packetBuffer.shift() ?? null;
61
+ if (packet)
62
+ connection.bufferedBytes -= packet.byteLength;
63
+ return packet;
64
+ };
65
+ const replaceIceCredentials = (sdp, ufrag, pwd) => sdp
66
+ .replace(/a=ice-ufrag:[^\r\n]+/g, `a=ice-ufrag:${ufrag}`)
67
+ .replace(/a=ice-pwd:[^\r\n]+/g, `a=ice-pwd:${pwd}`);
68
+ const replaceDtlsFingerprint = (sdp, algorithm, fingerprint) => sdp.replace(/a=fingerprint:[^\r\n]+/g, `a=fingerprint:${algorithm} ${fingerprint}`);
69
+ const removeIceCandidates = (sdp) => sdp
70
+ .replace(/a=candidate:[^\r\n]+\r?\n/g, "")
71
+ .replace(/a=end-of-candidates\r?\n?/g, "");
72
+ const appendRelayCandidate = (sdp, ip, port) => {
73
+ const candidate = `a=candidate:2 1 udp 2122262783 ${ip} ${port} typ host generation 0 network-cost 5`;
74
+ return `${removeIceCandidates(sdp)}${candidate}\r\na=end-of-candidates\r\n`;
75
+ };
76
+ const buildRemoteRelayAnswer = (offerSdp, info) => {
77
+ const setupLine = info.enableEdgerayDtlsActiveMode ? "a=setup:active" : "a=setup:passive";
78
+ let answerSdp = offerSdp.replace(/a=setup:actpass/g, setupLine);
79
+ answerSdp = replaceIceCredentials(answerSdp, info.authToken ?? info.token, info.key);
80
+ answerSdp = replaceDtlsFingerprint(answerSdp, "sha-256", RELAY_DTLS_FINGERPRINT);
81
+ answerSdp = answerSdp.replace(/a=ice-options:[^\r\n]+\r\n/g, "");
82
+ answerSdp = answerSdp.replace(/a=max-message-size:[^\r\n]+/g, "a=max-message-size:1200");
83
+ return appendRelayCandidate(answerSdp, info.ip, info.port);
84
+ };
85
+ const toArrayBuffer = (data) => {
86
+ const copy = new Uint8Array(data.byteLength);
87
+ copy.set(data);
88
+ return copy.buffer;
89
+ };
90
+ const toUint8Array = (data) => {
91
+ if (data instanceof Uint8Array)
92
+ return new Uint8Array(data);
93
+ if (Buffer.isBuffer(data))
94
+ return new Uint8Array(data);
95
+ if (data instanceof ArrayBuffer)
96
+ return new Uint8Array(data);
97
+ if (data && typeof data === "object" && "byteLength" in data && "buffer" in data) {
98
+ const view = data;
99
+ return new Uint8Array(view.buffer, view.byteOffset, view.byteLength);
100
+ }
101
+ return null;
102
+ };
103
+ const classifyRelayPacket = (packet) => {
104
+ if (packet.byteLength < 2)
105
+ return "non_stun";
106
+ const bytes = new Uint8Array(packet);
107
+ const first = bytes[0];
108
+ const second = bytes[1];
109
+ if ((first & 0xc0) !== 0)
110
+ return "non_stun";
111
+ const stunType = ((first & 0x3f) << 8) | second;
112
+ if (stunType === 0x0001)
113
+ return "stun_bind";
114
+ if (stunType === 0x0003)
115
+ return "stun_alloc";
116
+ return "stun_unknown";
117
+ };
118
+ const appendRelayPacketLog = (direction, connection, packet) => {
119
+ if (!RELAY_PACKET_LOG_PATH)
120
+ return;
121
+ const buffer = packet instanceof ArrayBuffer
122
+ ? Buffer.from(new Uint8Array(packet))
123
+ : Buffer.from(packet.buffer, packet.byteOffset, packet.byteLength);
124
+ appendFileSync(RELAY_PACKET_LOG_PATH, JSON.stringify({
125
+ ts: new Date().toISOString(),
126
+ direction,
127
+ id: connection.info.id,
128
+ relayId: connection.info.relayId,
129
+ relayName: connection.info.name,
130
+ ip: connection.info.ip,
131
+ rtcPort: connection.info.port,
132
+ voipPort: getVoipStackPort(connection.info),
133
+ size: buffer.byteLength,
134
+ hex: buffer.toString("hex"),
135
+ }) + "\n");
136
+ };
137
+ export class RelayRtcTransport {
138
+ config;
139
+ #relayInfoById = new Map();
140
+ #connections = new Map();
141
+ #totals = createEmptyStats();
142
+ #wrtcPromise = null;
143
+ constructor(config) {
144
+ this.config = config;
145
+ }
146
+ updateRelayList = (update) => {
147
+ const nextInfoById = new Map();
148
+ for (const relay of update.relays ?? []) {
149
+ if (relay.token_id == null || relay.token_id < 0 ||
150
+ relay.token_id >= (update.relay_tokens ?? []).length) {
151
+ continue;
152
+ }
153
+ const authToken = update.auth_tokens && relay.auth_token_id != null && relay.auth_token_id >= 0
154
+ ? update.auth_tokens[relay.auth_token_id]
155
+ : undefined;
156
+ for (const address of relay.addresses ?? []) {
157
+ if (address.protocol !== RELAY_PROTO_UDP)
158
+ continue;
159
+ if (address.ipv4 && address.port != null) {
160
+ const clientPort = USE_ORIGINAL_RELAY_PORTS ? address.port : TRUE_WEB_CLIENT_RELAY_PORT;
161
+ const id = getConnectionIdentifier(address.ipv4, clientPort);
162
+ nextInfoById.set(id, {
163
+ id,
164
+ relayId: relay.relay_id,
165
+ ip: address.ipv4,
166
+ port: clientPort,
167
+ originalPort: address.port,
168
+ isIPv6: false,
169
+ token: update.relay_tokens[relay.token_id],
170
+ authToken,
171
+ key: update.relay_key,
172
+ name: relay.relay_name,
173
+ enableEdgerayDtlsActiveMode: update.enable_edgeray_dtls_active_mode === true,
174
+ });
175
+ }
176
+ if (!DISABLE_IPV6 && address.ipv6 && address.port_v6 != null) {
177
+ const clientPort = USE_ORIGINAL_RELAY_PORTS ? address.port_v6 : TRUE_WEB_CLIENT_RELAY_PORT;
178
+ const id = getConnectionIdentifier(address.ipv6, clientPort);
179
+ nextInfoById.set(id, {
180
+ id,
181
+ relayId: relay.relay_id,
182
+ ip: address.ipv6,
183
+ port: clientPort,
184
+ originalPort: address.port_v6,
185
+ isIPv6: true,
186
+ token: update.relay_tokens[relay.token_id],
187
+ authToken,
188
+ key: update.relay_key,
189
+ name: relay.relay_name,
190
+ enableEdgerayDtlsActiveMode: update.enable_edgeray_dtls_active_mode === true,
191
+ });
192
+ }
193
+ }
194
+ }
195
+ for (const id of this.#relayInfoById.keys()) {
196
+ if (!nextInfoById.has(id))
197
+ this.#closeConnection(id);
198
+ }
199
+ this.#relayInfoById.clear();
200
+ for (const [id, info] of nextInfoById) {
201
+ this.#relayInfoById.set(id, info);
202
+ void this.#ensureConnection(info);
203
+ }
204
+ };
205
+ send = (packet, ip, port) => {
206
+ const requestedId = getConnectionIdentifier(ip, port);
207
+ const preferredPort = USE_ORIGINAL_RELAY_PORTS ? port : TRUE_WEB_CLIENT_RELAY_PORT;
208
+ const candidateIds = [
209
+ requestedId,
210
+ getConnectionIdentifier(ip, preferredPort),
211
+ getRelayLookupId(ip, TRUE_WEB_CLIENT_RELAY_PORT),
212
+ getRelayLookupId(ip, FAUX_WEB_CLIENT_RELAY_PORT),
213
+ ];
214
+ let info;
215
+ for (const candidateId of candidateIds) {
216
+ info = this.#relayInfoById.get(candidateId);
217
+ if (info)
218
+ break;
219
+ }
220
+ if (!info) {
221
+ if (DISABLE_IPV6 && ip.includes(":"))
222
+ return 0;
223
+ const earlyConnection = this.#getOrCreateEarlyConnection(ip, port);
224
+ bufferPacket(earlyConnection, toArrayBuffer(packet));
225
+ return packet.byteLength;
226
+ }
227
+ const connection = this.#getOrCreateConnection(info);
228
+ const arrayBuffer = toArrayBuffer(packet);
229
+ if (classifyRelayPacket(arrayBuffer) === "stun_alloc" &&
230
+ connection.state === "open" &&
231
+ connection.sentMedia &&
232
+ Date.now() - connection.lastRxPacketTime > ICE_RESTART_IDLE_THRESHOLD_MS) {
233
+ connection.packetBuffer = [];
234
+ connection.bufferedBytes = 0;
235
+ bufferPacket(connection, arrayBuffer);
236
+ void this.#restartIce(connection);
237
+ return packet.byteLength;
238
+ }
239
+ if (connection.state === "open" && connection.dataChannel?.readyState === "open") {
240
+ if (!this.#sendBufferedPacket(connection, arrayBuffer)) {
241
+ connection.stats.droppedPackets += 1;
242
+ }
243
+ return packet.byteLength;
244
+ }
245
+ bufferPacket(connection, arrayBuffer);
246
+ void this.#ensureConnection(info);
247
+ return packet.byteLength;
248
+ };
249
+ getStats = () => {
250
+ let openConnections = 0;
251
+ for (const connection of this.#connections.values()) {
252
+ if (connection.state === "open")
253
+ openConnections += 1;
254
+ }
255
+ return { ...this.#totals, openConnections };
256
+ };
257
+ closeAll = async () => {
258
+ for (const id of [...this.#connections.keys()])
259
+ this.#closeConnection(id);
260
+ };
261
+ // ─── private ──────────────────────────────────────────────────────────────
262
+ #getOrCreateConnection = (info) => {
263
+ const existing = this.#connections.get(info.id);
264
+ if (existing) {
265
+ existing.info = info;
266
+ return existing;
267
+ }
268
+ const created = {
269
+ info, state: "none", peerConnection: null, dataChannel: null,
270
+ iceCandidate: null, packetBuffer: [], bufferedBytes: 0,
271
+ connectPromise: null, connectionTimeout: null, iceStatsInterval: null,
272
+ lastIceRttMs: null, hasReceivedFirstPacket: false,
273
+ hasNonStunPacketSent: false, sentMedia: false, lastRxPacketTime: 0,
274
+ isReconnecting: false, stats: createEmptyStats(),
275
+ };
276
+ this.#connections.set(info.id, created);
277
+ return created;
278
+ };
279
+ #getOrCreateEarlyConnection = (ip, port) => {
280
+ const id = getConnectionIdentifier(ip, port);
281
+ const existing = this.#connections.get(id);
282
+ if (existing)
283
+ return existing;
284
+ const placeholderInfo = {
285
+ id, relayId: 0, ip, port, originalPort: port,
286
+ isIPv6: ip.includes(":"), token: "", key: "",
287
+ name: "early-packet", enableEdgerayDtlsActiveMode: false,
288
+ };
289
+ const created = {
290
+ info: placeholderInfo, state: "none", peerConnection: null,
291
+ dataChannel: null, iceCandidate: null, packetBuffer: [],
292
+ bufferedBytes: 0, connectPromise: null, connectionTimeout: null,
293
+ iceStatsInterval: null, lastIceRttMs: null,
294
+ hasReceivedFirstPacket: false, hasNonStunPacketSent: false,
295
+ sentMedia: false, lastRxPacketTime: 0, isReconnecting: false,
296
+ stats: createEmptyStats(),
297
+ };
298
+ this.#connections.set(id, created);
299
+ return created;
300
+ };
301
+ #ensureConnection = async (info) => {
302
+ const connection = this.#getOrCreateConnection(info);
303
+ if (connection.state === "open" || connection.state === "connecting") {
304
+ return connection.connectPromise ?? Promise.resolve();
305
+ }
306
+ const promise = this.#connect(connection);
307
+ connection.connectPromise = promise;
308
+ try {
309
+ await promise;
310
+ }
311
+ finally {
312
+ connection.connectPromise = null;
313
+ }
314
+ };
315
+ #connect = async (connection) => {
316
+ const wrtcModule = await this.#loadWrtc();
317
+ const { RTCPeerConnection } = wrtcModule;
318
+ if (typeof RTCPeerConnection !== "function") {
319
+ throw new Error("RTCPeerConnection unavailable from @roamhq/wrtc");
320
+ }
321
+ this.#closePeerObjects(connection);
322
+ connection.state = "connecting";
323
+ const pc = new RTCPeerConnection();
324
+ const dc = pc.createDataChannel("pre-negotiated", {
325
+ negotiated: true, id: 0, ordered: false, maxRetransmits: 0, priority: "high",
326
+ });
327
+ connection.peerConnection = pc;
328
+ connection.dataChannel = dc;
329
+ dc.binaryType = "arraybuffer";
330
+ dc.onopen = () => {
331
+ connection.state = "open";
332
+ connection.isReconnecting = false;
333
+ if (connection.connectionTimeout) {
334
+ clearTimeout(connection.connectionTimeout);
335
+ connection.connectionTimeout = null;
336
+ }
337
+ this.#flushBufferedPackets(connection);
338
+ this.#startIceRttPolling(connection);
339
+ };
340
+ dc.onclose = () => {
341
+ if (connection.state !== "failed")
342
+ connection.state = "closed";
343
+ };
344
+ dc.onerror = () => {
345
+ connection.state = "failed";
346
+ };
347
+ dc.onmessage = (event) => {
348
+ this.#handleIncomingPacket(connection, event.data);
349
+ };
350
+ pc.onicecandidate = (event) => {
351
+ if (event.candidate?.candidate && !connection.iceCandidate) {
352
+ connection.iceCandidate = event.candidate.candidate;
353
+ }
354
+ };
355
+ pc.oniceconnectionstatechange = () => {
356
+ if (pc.iceConnectionState === "failed" || pc.iceConnectionState === "closed") {
357
+ connection.state = "failed";
358
+ }
359
+ };
360
+ connection.connectionTimeout = setTimeout(() => {
361
+ if (connection.state === "connecting") {
362
+ connection.state = "failed";
363
+ this.#closePeerObjects(connection);
364
+ }
365
+ }, CONNECTION_TIMEOUT_MS);
366
+ const offer = await pc.createOffer();
367
+ await pc.setLocalDescription(offer);
368
+ const remoteSdp = buildRemoteRelayAnswer(offer.sdp ?? "", {
369
+ ...connection.info,
370
+ port: getRtcConnectPort(connection.info),
371
+ });
372
+ await pc.setRemoteDescription({ type: "answer", sdp: remoteSdp });
373
+ };
374
+ #restartIce = async (connection) => {
375
+ if (connection.isReconnecting || !connection.hasNonStunPacketSent)
376
+ return;
377
+ const { RTCPeerConnection } = await this.#loadWrtc();
378
+ if (typeof RTCPeerConnection !== "function")
379
+ return;
380
+ connection.isReconnecting = true;
381
+ try {
382
+ this.#closePeerObjects(connection);
383
+ connection.state = "connecting";
384
+ const pc = new RTCPeerConnection();
385
+ const dc = pc.createDataChannel("pre-negotiated", {
386
+ negotiated: true, id: 0, ordered: false, maxRetransmits: 0, priority: "high",
387
+ });
388
+ connection.peerConnection = pc;
389
+ connection.dataChannel = dc;
390
+ dc.binaryType = "arraybuffer";
391
+ dc.onopen = () => {
392
+ connection.state = "open";
393
+ connection.isReconnecting = false;
394
+ this.#flushBufferedPackets(connection);
395
+ this.#startIceRttPolling(connection);
396
+ };
397
+ dc.onclose = () => { if (connection.state !== "failed")
398
+ connection.state = "closed"; };
399
+ dc.onerror = () => { connection.state = "failed"; };
400
+ dc.onmessage = (event) => {
401
+ this.#handleIncomingPacket(connection, event.data);
402
+ };
403
+ pc.onicecandidate = (event) => {
404
+ if (event.candidate?.candidate && !connection.iceCandidate) {
405
+ connection.iceCandidate = event.candidate.candidate;
406
+ }
407
+ };
408
+ const offer = await pc.createOffer({ iceRestart: false });
409
+ let localSdp = offer.sdp ?? "";
410
+ if (connection.iceCandidate) {
411
+ localSdp = `${removeIceCandidates(localSdp)}a=${connection.iceCandidate}\r\na=end-of-candidates\r\n`;
412
+ }
413
+ await pc.setLocalDescription({ type: "offer", sdp: localSdp });
414
+ const remoteSdp = buildRemoteRelayAnswer(localSdp, {
415
+ ...connection.info,
416
+ port: getRtcConnectPort(connection.info),
417
+ });
418
+ await pc.setRemoteDescription({ type: "answer", sdp: remoteSdp });
419
+ }
420
+ catch {
421
+ connection.state = "failed";
422
+ }
423
+ finally {
424
+ connection.isReconnecting = false;
425
+ }
426
+ };
427
+ #handleIncomingPacket = (connection, raw) => {
428
+ const packet = toUint8Array(raw);
429
+ if (!packet)
430
+ return;
431
+ connection.stats.receivedPackets += 1;
432
+ connection.stats.receivedBytes += packet.byteLength;
433
+ connection.hasReceivedFirstPacket = true;
434
+ connection.lastRxPacketTime = Date.now();
435
+ this.#totals.receivedPackets += 1;
436
+ this.#totals.receivedBytes += packet.byteLength;
437
+ appendRelayPacketLog("recv", connection, packet);
438
+ this.config.onTransportMessage(packet, connection.info.ip, getVoipStackPort(connection.info));
439
+ };
440
+ #flushBufferedPackets = (connection) => {
441
+ while (connection.state === "open" &&
442
+ connection.dataChannel?.readyState === "open" &&
443
+ connection.packetBuffer.length > 0) {
444
+ const packet = shiftPacket(connection);
445
+ if (!packet)
446
+ break;
447
+ if (!this.#sendBufferedPacket(connection, packet)) {
448
+ connection.stats.droppedPackets += 1;
449
+ break;
450
+ }
451
+ }
452
+ };
453
+ #sendBufferedPacket = (connection, packet) => {
454
+ try {
455
+ connection.dataChannel?.send(packet);
456
+ if (classifyRelayPacket(packet) === "non_stun") {
457
+ connection.hasNonStunPacketSent = true;
458
+ connection.sentMedia = true;
459
+ }
460
+ connection.stats.sentPackets += 1;
461
+ connection.stats.sentBytes += packet.byteLength;
462
+ this.#totals.sentPackets += 1;
463
+ this.#totals.sentBytes += packet.byteLength;
464
+ appendRelayPacketLog("send", connection, packet);
465
+ return true;
466
+ }
467
+ catch {
468
+ return false;
469
+ }
470
+ };
471
+ #startIceRttPolling = (connection) => {
472
+ this.#stopIceRttPolling(connection);
473
+ const pc = connection.peerConnection;
474
+ if (!pc || typeof pc.getStats !== "function" || !this.config.onIceRtt)
475
+ return;
476
+ const poll = async () => {
477
+ const rttMs = await this.#readCurrentRoundTripTimeMs(pc);
478
+ if (rttMs == null || connection.lastIceRttMs === rttMs)
479
+ return;
480
+ connection.lastIceRttMs = rttMs;
481
+ this.config.onIceRtt?.(rttMs, connection.info.ip, connection.info.port);
482
+ };
483
+ void poll();
484
+ connection.iceStatsInterval = setInterval(() => { void poll(); }, ICE_RTT_POLL_MS);
485
+ connection.iceStatsInterval.unref?.();
486
+ };
487
+ #stopIceRttPolling = (connection) => {
488
+ if (connection.iceStatsInterval) {
489
+ clearInterval(connection.iceStatsInterval);
490
+ connection.iceStatsInterval = null;
491
+ }
492
+ connection.lastIceRttMs = null;
493
+ };
494
+ #readCurrentRoundTripTimeMs = async (pc) => {
495
+ try {
496
+ const stats = await pc.getStats();
497
+ const reports = stats && typeof stats.values === "function"
498
+ ? Array.from(stats.values())
499
+ : Array.isArray(stats) ? stats : Object.values(stats ?? {});
500
+ if (!reports.length)
501
+ return null;
502
+ let selectedCandidatePairId = "";
503
+ for (const report of reports) {
504
+ if (report?.type === "transport" && typeof report.selectedCandidatePairId === "string") {
505
+ selectedCandidatePairId = report.selectedCandidatePairId;
506
+ break;
507
+ }
508
+ }
509
+ const candidatePairs = reports.filter((r) => r?.type === "candidate-pair");
510
+ const selectedPair = (selectedCandidatePairId && candidatePairs.find((r) => r?.id === selectedCandidatePairId)) ||
511
+ candidatePairs.find((r) => r?.selected || r?.nominated) ||
512
+ candidatePairs[0];
513
+ const rttSeconds = typeof selectedPair?.currentRoundTripTime === "number"
514
+ ? selectedPair.currentRoundTripTime
515
+ : typeof selectedPair?.totalRoundTripTime === "number" &&
516
+ typeof selectedPair?.responsesReceived === "number" &&
517
+ selectedPair.responsesReceived > 0
518
+ ? selectedPair.totalRoundTripTime / selectedPair.responsesReceived
519
+ : null;
520
+ if (rttSeconds == null || !Number.isFinite(rttSeconds) || rttSeconds <= 0)
521
+ return null;
522
+ return Math.max(1, Math.round(rttSeconds * 1000));
523
+ }
524
+ catch {
525
+ return null;
526
+ }
527
+ };
528
+ #closeConnection = (id) => {
529
+ const connection = this.#connections.get(id);
530
+ if (!connection)
531
+ return;
532
+ if (connection.connectionTimeout) {
533
+ clearTimeout(connection.connectionTimeout);
534
+ connection.connectionTimeout = null;
535
+ }
536
+ this.#closePeerObjects(connection);
537
+ connection.state = "closed";
538
+ connection.packetBuffer = [];
539
+ connection.bufferedBytes = 0;
540
+ this.#connections.delete(id);
541
+ };
542
+ #closePeerObjects = (connection) => {
543
+ this.#stopIceRttPolling(connection);
544
+ try {
545
+ connection.dataChannel?.close?.();
546
+ }
547
+ catch { }
548
+ try {
549
+ connection.peerConnection?.close?.();
550
+ }
551
+ catch { }
552
+ connection.dataChannel = null;
553
+ connection.peerConnection = null;
554
+ };
555
+ // JAP@Fix: helpful error when the optional @roamhq/wrtc dep is missing
556
+ #loadWrtc = () => {
557
+ this.#wrtcPromise ??= import("@roamhq/wrtc").then((module) => (module.default ?? module)).catch((err) => {
558
+ this.#wrtcPromise = null;
559
+ throw new Error(`VoIP relay needs the optional "@roamhq/wrtc" package (npm i @roamhq/wrtc). Original error: ${err?.message || err}`);
560
+ });
561
+ return this.#wrtcPromise;
562
+ };
563
+ }
@@ -0,0 +1,26 @@
1
+ export interface SignalingBridgeConfig {
2
+ sock: any;
3
+ /** Observer fired on inbound call offers (surfaced by VoipClient as 'incoming-call'). */
4
+ onIncomingCall?: (info: any) => void;
5
+ }
6
+
7
+ /** E2EE call-signaling transport: offers/answers/receipts overChat stanzas + tcToken/Signal session setup. */
8
+ export class SignalingBridge {
9
+ constructor(config: SignalingBridgeConfig);
10
+ attachEngine(voip: any): void;
11
+ init(): Promise<void>;
12
+ sendSignaling(peerJid: string, callId: string, xmlPayload: string): any;
13
+ processIncomingCall(node: any, voip: any, activeCallId: string | null): any;
14
+ processIncomingReceipt(node: any, voip: any, activeCallId: string | null): any;
15
+ requestTcToken(jid: string): Promise<any>;
16
+ ensureTcToken(...jids: string[]): Promise<any>;
17
+ discoverPeerDevices(peerLidJid: string): Promise<any>;
18
+ ensureSessionsForPeers(jids: string[]): Promise<any>;
19
+ resolveLid(pnJid: string): Promise<any>;
20
+ issueTcToken(jid: string): Promise<any>;
21
+ getRemoteDeviceJid(callId: string): any;
22
+ getPendingOffer(callId: string): any;
23
+ hasPendingOffer(callId: string): boolean;
24
+ listPendingOffers(): any[];
25
+ takePendingOffer(callId: string): any;
26
+ }