zapo-js 0.2.0 → 0.3.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 (351) hide show
  1. package/README.md +7 -3
  2. package/dist/appstate/WaAppStateCrypto.js +49 -41
  3. package/dist/appstate/WaAppStateSyncClient.js +79 -42
  4. package/dist/appstate/index.js +2 -2
  5. package/dist/auth/WaAuthClient.js +20 -11
  6. package/dist/auth/{flow/WaAuthCredentialsFlow.js → credentials-flow.js} +83 -18
  7. package/dist/auth/pairing/WaPairingFlow.js +26 -29
  8. package/dist/auth/pairing/{WaPairingCodeCrypto.js → pairing-code-crypto.js} +29 -13
  9. package/dist/client/WaClient.js +115 -75
  10. package/dist/client/WaClientFactory.js +113 -30
  11. package/dist/client/connection/WaConnectionManager.js +4 -1
  12. package/dist/client/coordinators/WaAbPropsCoordinator.js +141 -0
  13. package/dist/client/coordinators/WaBusinessCoordinator.js +3 -12
  14. package/dist/client/coordinators/WaEmailCoordinator.js +63 -0
  15. package/dist/client/coordinators/WaIncomingNodeCoordinator.js +33 -8
  16. package/dist/client/coordinators/WaMessageDispatchCoordinator.js +55 -25
  17. package/dist/client/coordinators/WaOfflineResumeCoordinator.js +114 -0
  18. package/dist/client/coordinators/WaPassiveTasksCoordinator.js +38 -20
  19. package/dist/client/coordinators/WaProfileCoordinator.js +3 -1
  20. package/dist/client/coordinators/WaRetryCoordinator.js +11 -9
  21. package/dist/client/coordinators/WaTrustedContactTokenCoordinator.js +22 -4
  22. package/dist/client/dirty.js +1 -1
  23. package/dist/client/events/abprops.js +43 -0
  24. package/dist/client/events/privacy-token.js +1 -2
  25. package/dist/client/events/registration.js +42 -0
  26. package/dist/client/incoming.js +37 -0
  27. package/dist/client/mailbox.js +17 -1
  28. package/dist/client/media.js +243 -0
  29. package/dist/client/messages.js +163 -86
  30. package/dist/crypto/core/index.js +4 -1
  31. package/dist/crypto/core/random.js +3 -9
  32. package/dist/crypto/core/xeddsa.js +57 -0
  33. package/dist/crypto/curves/X25519.js +18 -0
  34. package/dist/crypto/curves/constants.js +2 -1
  35. package/dist/esm/appstate/WaAppStateCrypto.js +39 -31
  36. package/dist/esm/appstate/WaAppStateSyncClient.js +68 -31
  37. package/dist/esm/appstate/index.js +1 -1
  38. package/dist/esm/appstate/{WaAppStateSyncResponseParser.js → response-parser.js} +1 -1
  39. package/dist/esm/auth/WaAuthClient.js +17 -8
  40. package/dist/esm/auth/{flow/WaAuthCredentialsFlow.js → credentials-flow.js} +83 -18
  41. package/dist/esm/auth/pairing/WaPairingFlow.js +25 -28
  42. package/dist/esm/auth/pairing/{WaPairingCodeCrypto.js → pairing-code-crypto.js} +20 -6
  43. package/dist/esm/client/WaClient.js +116 -76
  44. package/dist/esm/client/WaClientFactory.js +114 -31
  45. package/dist/esm/client/connection/WaConnectionManager.js +4 -1
  46. package/dist/esm/client/coordinators/WaAbPropsCoordinator.js +137 -0
  47. package/dist/esm/client/coordinators/WaBusinessCoordinator.js +4 -13
  48. package/dist/esm/client/coordinators/WaEmailCoordinator.js +60 -0
  49. package/dist/esm/client/coordinators/WaIncomingNodeCoordinator.js +35 -10
  50. package/dist/esm/client/coordinators/WaMessageDispatchCoordinator.js +47 -17
  51. package/dist/esm/client/coordinators/WaOfflineResumeCoordinator.js +110 -0
  52. package/dist/esm/client/coordinators/WaPassiveTasksCoordinator.js +38 -20
  53. package/dist/esm/client/coordinators/WaProfileCoordinator.js +3 -1
  54. package/dist/esm/client/coordinators/WaRetryCoordinator.js +11 -9
  55. package/dist/esm/client/coordinators/WaTrustedContactTokenCoordinator.js +24 -6
  56. package/dist/esm/client/dirty.js +1 -1
  57. package/dist/esm/client/events/abprops.js +40 -0
  58. package/dist/esm/client/events/privacy-token.js +1 -2
  59. package/dist/esm/client/events/registration.js +39 -0
  60. package/dist/esm/client/incoming.js +36 -0
  61. package/dist/esm/client/mailbox.js +17 -1
  62. package/dist/esm/client/media.js +234 -0
  63. package/dist/esm/client/messages.js +162 -85
  64. package/dist/esm/crypto/core/index.js +1 -0
  65. package/dist/esm/crypto/core/random.js +2 -7
  66. package/dist/esm/crypto/core/xeddsa.js +53 -0
  67. package/dist/esm/crypto/curves/X25519.js +20 -2
  68. package/dist/esm/crypto/curves/constants.js +1 -0
  69. package/dist/esm/infra/perf/StoreLock.js +7 -4
  70. package/dist/esm/media/WaMediaCrypto.js +257 -62
  71. package/dist/esm/media/WaMediaTransferClient.js +47 -190
  72. package/dist/esm/media/constants.js +2 -0
  73. package/dist/esm/media/processor.js +1 -0
  74. package/dist/esm/message/addon-crypto.js +130 -3
  75. package/dist/esm/message/content.js +12 -6
  76. package/dist/esm/message/icdc.js +8 -8
  77. package/dist/esm/message/incoming.js +14 -12
  78. package/dist/esm/message/phash.js +32 -12
  79. package/dist/esm/message/reporting-token.js +3 -3
  80. package/dist/esm/message/use-case-secret.js +1 -1
  81. package/dist/esm/protocol/abprops.js +159 -0
  82. package/dist/esm/protocol/browser.js +14 -0
  83. package/dist/esm/protocol/constants.js +3 -1
  84. package/dist/esm/protocol/email.js +30 -0
  85. package/dist/esm/protocol/jid.js +44 -10
  86. package/dist/esm/protocol/nodes.js +6 -2
  87. package/dist/esm/protocol/notification.js +7 -1
  88. package/dist/esm/retry/reason.js +1 -1
  89. package/dist/esm/signal/api/SignalDeviceSyncApi.js +5 -2
  90. package/dist/esm/signal/api/SignalDigestSyncApi.js +8 -6
  91. package/dist/esm/signal/api/SignalIdentitySyncApi.js +4 -4
  92. package/dist/esm/signal/api/SignalMissingPreKeysSyncApi.js +1 -1
  93. package/dist/esm/signal/api/SignalSessionSyncApi.js +1 -1
  94. package/dist/esm/signal/crypto/WaAdvSignature.js +5 -51
  95. package/dist/esm/signal/crypto/constants.js +0 -4
  96. package/dist/esm/signal/encoding.js +11 -54
  97. package/dist/esm/signal/group/SenderKeyChain.js +3 -3
  98. package/dist/esm/signal/group/SenderKeyCodec.js +5 -6
  99. package/dist/esm/signal/group/SenderKeyManager.js +13 -10
  100. package/dist/esm/signal/registration/keygen.js +2 -3
  101. package/dist/esm/signal/registration/utils.js +2 -2
  102. package/dist/esm/signal/session/SignalProtocol.js +18 -17
  103. package/dist/esm/signal/session/SignalRatchet.js +21 -10
  104. package/dist/esm/signal/session/SignalSerializer.js +5 -6
  105. package/dist/esm/signal/session/SignalSession.js +11 -9
  106. package/dist/esm/signal/session/resolver.js +6 -6
  107. package/dist/esm/store/contracts/identity.store.js +1 -0
  108. package/dist/esm/store/contracts/message-secret.store.js +1 -0
  109. package/dist/esm/store/contracts/pre-key.store.js +1 -0
  110. package/dist/esm/store/contracts/session.store.js +1 -0
  111. package/dist/esm/store/createStore.js +48 -12
  112. package/dist/esm/store/index.js +4 -0
  113. package/dist/esm/store/locks/identity.lock.js +16 -0
  114. package/dist/esm/store/locks/message-secret.lock.js +17 -0
  115. package/dist/esm/store/locks/pre-key.lock.js +27 -0
  116. package/dist/esm/store/locks/session.lock.js +19 -0
  117. package/dist/esm/store/locks/signal.lock.js +0 -24
  118. package/dist/esm/store/noop.store.js +20 -0
  119. package/dist/esm/store/providers/memory/device-list.store.js +3 -0
  120. package/dist/esm/store/providers/memory/identity.store.js +31 -0
  121. package/dist/esm/store/providers/memory/message-secret.store.js +81 -0
  122. package/dist/esm/store/providers/memory/participants.store.js +3 -0
  123. package/dist/esm/store/providers/memory/pre-key.store.js +97 -0
  124. package/dist/esm/store/providers/memory/retry.store.js +25 -11
  125. package/dist/esm/store/providers/memory/session.store.js +45 -0
  126. package/dist/esm/store/providers/memory/signal.store.js +1 -164
  127. package/dist/esm/transport/WaComms.js +4 -3
  128. package/dist/esm/transport/WaWebSocket.js +9 -1
  129. package/dist/esm/transport/index.js +6 -0
  130. package/dist/esm/transport/keepalive/WaKeepAlive.js +17 -8
  131. package/dist/esm/transport/node/WaMobileTcpSocket.js +114 -0
  132. package/dist/esm/transport/node/WaNodeOrchestrator.js +17 -8
  133. package/dist/esm/transport/node/builders/abprops.js +20 -0
  134. package/dist/esm/transport/node/builders/device.js +11 -0
  135. package/dist/esm/transport/node/builders/email.js +65 -0
  136. package/dist/esm/transport/node/builders/offline.js +14 -0
  137. package/dist/esm/transport/node/builders/prekeys.js +37 -40
  138. package/dist/esm/transport/node/builders/presence.js +13 -0
  139. package/dist/esm/transport/node/builders/privacy-token.js +19 -23
  140. package/dist/esm/transport/node/builders/retry.js +1 -1
  141. package/dist/esm/transport/node/helpers.js +24 -0
  142. package/dist/esm/transport/node/mex/argo-decoder.js +152 -0
  143. package/dist/esm/transport/node/mex/client.js +83 -0
  144. package/dist/esm/transport/node/mex/persist-ids.js +10 -0
  145. package/dist/esm/transport/noise/WaClientPayload.js +15 -10
  146. package/dist/esm/transport/noise/WaFrameCodec.js +2 -2
  147. package/dist/esm/transport/noise/WaMobileClientPayload.js +53 -0
  148. package/dist/esm/transport/noise/WaNoiseCert.js +9 -27
  149. package/dist/esm/transport/noise/WaNoiseSession.js +12 -11
  150. package/dist/infra/perf/StoreLock.js +7 -4
  151. package/dist/media/WaMediaCrypto.js +253 -58
  152. package/dist/media/WaMediaTransferClient.js +50 -223
  153. package/dist/media/constants.js +3 -1
  154. package/dist/media/processor.js +2 -0
  155. package/dist/message/addon-crypto.js +131 -0
  156. package/dist/message/content.js +13 -5
  157. package/dist/message/icdc.js +8 -8
  158. package/dist/message/incoming.js +14 -12
  159. package/dist/message/phash.js +32 -12
  160. package/dist/message/reporting-token.js +2 -2
  161. package/dist/message/use-case-secret.js +1 -1
  162. package/dist/protocol/abprops.js +163 -0
  163. package/dist/protocol/browser.js +15 -0
  164. package/dist/protocol/constants.js +14 -2
  165. package/dist/protocol/email.js +33 -0
  166. package/dist/protocol/jid.js +45 -10
  167. package/dist/protocol/nodes.js +6 -2
  168. package/dist/protocol/notification.js +8 -2
  169. package/dist/retry/reason.js +1 -1
  170. package/dist/signal/api/SignalDeviceSyncApi.js +5 -2
  171. package/dist/signal/api/SignalDigestSyncApi.js +8 -6
  172. package/dist/signal/api/SignalIdentitySyncApi.js +4 -4
  173. package/dist/signal/crypto/WaAdvSignature.js +2 -50
  174. package/dist/signal/crypto/constants.js +1 -5
  175. package/dist/signal/encoding.js +11 -49
  176. package/dist/signal/group/SenderKeyChain.js +2 -2
  177. package/dist/signal/group/SenderKeyCodec.js +4 -5
  178. package/dist/signal/group/SenderKeyManager.js +12 -9
  179. package/dist/signal/registration/keygen.js +1 -2
  180. package/dist/signal/registration/utils.js +2 -2
  181. package/dist/signal/session/SignalProtocol.js +18 -17
  182. package/dist/signal/session/SignalRatchet.js +19 -8
  183. package/dist/signal/session/SignalSerializer.js +5 -6
  184. package/dist/signal/session/SignalSession.js +11 -9
  185. package/dist/signal/session/resolver.js +6 -6
  186. package/dist/store/contracts/identity.store.js +2 -0
  187. package/dist/store/contracts/message-secret.store.js +2 -0
  188. package/dist/store/contracts/pre-key.store.js +2 -0
  189. package/dist/store/contracts/session.store.js +2 -0
  190. package/dist/store/createStore.js +47 -11
  191. package/dist/store/index.js +9 -1
  192. package/dist/store/locks/identity.lock.js +19 -0
  193. package/dist/store/locks/message-secret.lock.js +20 -0
  194. package/dist/store/locks/pre-key.lock.js +30 -0
  195. package/dist/store/locks/session.lock.js +22 -0
  196. package/dist/store/locks/signal.lock.js +0 -24
  197. package/dist/store/noop.store.js +21 -1
  198. package/dist/store/providers/memory/device-list.store.js +3 -0
  199. package/dist/store/providers/memory/identity.store.js +35 -0
  200. package/dist/store/providers/memory/message-secret.store.js +85 -0
  201. package/dist/store/providers/memory/participants.store.js +3 -0
  202. package/dist/store/providers/memory/pre-key.store.js +101 -0
  203. package/dist/store/providers/memory/retry.store.js +24 -10
  204. package/dist/store/providers/memory/session.store.js +49 -0
  205. package/dist/store/providers/memory/signal.store.js +1 -164
  206. package/dist/transport/WaComms.js +4 -3
  207. package/dist/transport/WaWebSocket.js +9 -1
  208. package/dist/transport/index.js +17 -1
  209. package/dist/transport/keepalive/WaKeepAlive.js +17 -8
  210. package/dist/transport/node/WaMobileTcpSocket.js +118 -0
  211. package/dist/transport/node/WaNodeOrchestrator.js +16 -7
  212. package/dist/transport/node/builders/abprops.js +23 -0
  213. package/dist/transport/node/builders/device.js +14 -0
  214. package/dist/transport/node/builders/email.js +72 -0
  215. package/dist/transport/node/builders/offline.js +17 -0
  216. package/dist/transport/node/builders/prekeys.js +36 -39
  217. package/dist/transport/node/builders/presence.js +16 -0
  218. package/dist/transport/node/builders/privacy-token.js +18 -22
  219. package/dist/transport/node/builders/retry.js +1 -1
  220. package/dist/transport/node/helpers.js +26 -0
  221. package/dist/transport/node/mex/argo-decoder.js +189 -0
  222. package/dist/transport/node/mex/client.js +86 -0
  223. package/dist/transport/node/mex/persist-ids.js +13 -0
  224. package/dist/transport/noise/WaClientPayload.js +14 -9
  225. package/dist/transport/noise/WaFrameCodec.js +1 -1
  226. package/dist/transport/noise/WaMobileClientPayload.js +56 -0
  227. package/dist/transport/noise/WaNoiseCert.js +8 -26
  228. package/dist/transport/noise/WaNoiseSession.js +11 -10
  229. package/dist/types/appstate/WaAppStateCrypto.d.ts +11 -8
  230. package/dist/types/appstate/WaAppStateSyncClient.d.ts +6 -2
  231. package/dist/types/appstate/index.d.ts +1 -1
  232. package/dist/types/appstate/{WaAppStateSyncResponseParser.d.ts → response-parser.d.ts} +1 -1
  233. package/dist/types/appstate/types.d.ts +1 -1
  234. package/dist/types/auth/WaAuthClient.d.ts +9 -3
  235. package/dist/types/auth/credentials-flow.d.ts +20 -0
  236. package/dist/types/auth/pairing/WaPairingFlow.d.ts +3 -2
  237. package/dist/types/auth/pairing/{WaPairingCodeCrypto.d.ts → pairing-code-crypto.d.ts} +6 -1
  238. package/dist/types/auth/types.d.ts +40 -0
  239. package/dist/types/client/WaClient.d.ts +19 -8
  240. package/dist/types/client/WaClientFactory.d.ts +10 -4
  241. package/dist/types/client/coordinators/WaAbPropsCoordinator.d.ts +26 -0
  242. package/dist/types/client/coordinators/WaBusinessCoordinator.d.ts +1 -1
  243. package/dist/types/client/coordinators/WaEmailCoordinator.d.ts +24 -0
  244. package/dist/types/client/coordinators/WaIncomingNodeCoordinator.d.ts +6 -1
  245. package/dist/types/client/coordinators/WaMessageDispatchCoordinator.d.ts +15 -2
  246. package/dist/types/client/coordinators/WaOfflineResumeCoordinator.d.ts +31 -0
  247. package/dist/types/client/coordinators/WaPassiveTasksCoordinator.d.ts +13 -2
  248. package/dist/types/client/coordinators/WaPrivacyCoordinator.d.ts +1 -1
  249. package/dist/types/client/coordinators/WaProfileCoordinator.d.ts +4 -2
  250. package/dist/types/client/coordinators/WaRetryCoordinator.d.ts +6 -0
  251. package/dist/types/client/coordinators/WaTrustedContactTokenCoordinator.d.ts +11 -1
  252. package/dist/types/client/dirty.d.ts +3 -1
  253. package/dist/types/client/events/abprops.d.ts +14 -0
  254. package/dist/types/client/events/registration.d.ts +17 -0
  255. package/dist/types/client/incoming.d.ts +6 -1
  256. package/dist/types/client/mailbox.d.ts +2 -0
  257. package/dist/types/client/media.d.ts +31 -0
  258. package/dist/types/client/messages.d.ts +2 -0
  259. package/dist/types/client/persistence/WriteBehindPersistence.d.ts +1 -1
  260. package/dist/types/client/types.d.ts +100 -1
  261. package/dist/types/crypto/core/index.d.ts +1 -0
  262. package/dist/types/crypto/core/primitives.d.ts +1 -1
  263. package/dist/types/crypto/core/random.d.ts +1 -1
  264. package/dist/types/crypto/core/xeddsa.d.ts +2 -0
  265. package/dist/types/crypto/curves/constants.d.ts +1 -0
  266. package/dist/types/crypto/index.d.ts +1 -0
  267. package/dist/types/index.d.ts +2 -1
  268. package/dist/types/infra/log/ConsoleLogger.d.ts +1 -1
  269. package/dist/types/infra/log/PinoLogger.d.ts +1 -1
  270. package/dist/types/infra/perf/StoreLock.d.ts +1 -0
  271. package/dist/types/media/WaMediaCrypto.d.ts +15 -6
  272. package/dist/types/media/WaMediaTransferClient.d.ts +3 -11
  273. package/dist/types/media/constants.d.ts +2 -0
  274. package/dist/types/media/index.d.ts +1 -0
  275. package/dist/types/media/processor.d.ts +28 -0
  276. package/dist/types/media/types.d.ts +9 -3
  277. package/dist/types/message/addon-crypto.d.ts +34 -3
  278. package/dist/types/message/content.d.ts +3 -1
  279. package/dist/types/message/icdc.d.ts +4 -4
  280. package/dist/types/message/types.d.ts +16 -24
  281. package/dist/types/protocol/abprops.d.ts +142 -0
  282. package/dist/types/protocol/browser.d.ts +1 -0
  283. package/dist/types/protocol/constants.d.ts +5 -1
  284. package/dist/types/protocol/email.d.ts +32 -0
  285. package/dist/types/protocol/jid.d.ts +1 -0
  286. package/dist/types/protocol/nodes.d.ts +4 -0
  287. package/dist/types/protocol/notification.d.ts +6 -0
  288. package/dist/types/protocol/stream.d.ts +1 -0
  289. package/dist/types/retry/reason.d.ts +1 -1
  290. package/dist/types/signal/api/SignalDigestSyncApi.d.ts +3 -0
  291. package/dist/types/signal/api/SignalIdentitySyncApi.d.ts +3 -3
  292. package/dist/types/signal/crypto/WaAdvSignature.d.ts +0 -2
  293. package/dist/types/signal/crypto/constants.d.ts +0 -1
  294. package/dist/types/signal/encoding.d.ts +7 -1
  295. package/dist/types/signal/group/SenderKeyChain.d.ts +1 -1
  296. package/dist/types/signal/group/SenderKeyManager.d.ts +7 -2
  297. package/dist/types/signal/registration/utils.d.ts +2 -1
  298. package/dist/types/signal/session/SignalProtocol.d.ts +11 -2
  299. package/dist/types/signal/session/SignalSerializer.d.ts +2 -1
  300. package/dist/types/signal/session/resolver.d.ts +4 -2
  301. package/dist/types/signal/types.d.ts +16 -4
  302. package/dist/types/store/contracts/identity.store.d.ts +11 -0
  303. package/dist/types/store/contracts/message-secret.store.d.ts +16 -0
  304. package/dist/types/store/contracts/pre-key.store.d.ts +13 -0
  305. package/dist/types/store/contracts/session.store.d.ts +14 -0
  306. package/dist/types/store/contracts/signal.store.d.ts +1 -34
  307. package/dist/types/store/index.d.ts +9 -1
  308. package/dist/types/store/locks/identity.lock.d.ts +3 -0
  309. package/dist/types/store/locks/message-secret.lock.d.ts +3 -0
  310. package/dist/types/store/locks/pre-key.lock.d.ts +3 -0
  311. package/dist/types/store/locks/session.lock.d.ts +3 -0
  312. package/dist/types/store/noop.store.d.ts +4 -0
  313. package/dist/types/store/providers/memory/identity.store.d.ts +18 -0
  314. package/dist/types/store/providers/memory/message-secret.store.d.ts +21 -0
  315. package/dist/types/store/providers/memory/pre-key.store.d.ts +23 -0
  316. package/dist/types/store/providers/memory/retry.store.d.ts +7 -1
  317. package/dist/types/store/providers/memory/session.store.d.ts +21 -0
  318. package/dist/types/store/providers/memory/signal.store.d.ts +3 -45
  319. package/dist/types/store/providers/memory/thread.store.d.ts +1 -1
  320. package/dist/types/store/types.d.ts +21 -1
  321. package/dist/types/transport/WaWebSocket.d.ts +1 -0
  322. package/dist/types/transport/index.d.ts +8 -1
  323. package/dist/types/transport/keepalive/WaKeepAlive.d.ts +4 -1
  324. package/dist/types/transport/node/WaMobileTcpSocket.d.ts +18 -0
  325. package/dist/types/transport/node/WaNodeOrchestrator.d.ts +6 -2
  326. package/dist/types/transport/node/builders/abprops.d.ts +5 -0
  327. package/dist/types/transport/node/builders/device.d.ts +2 -0
  328. package/dist/types/transport/node/builders/email.d.ts +11 -0
  329. package/dist/types/transport/node/builders/offline.d.ts +2 -0
  330. package/dist/types/transport/node/builders/prekeys.d.ts +4 -3
  331. package/dist/types/transport/node/builders/presence.d.ts +6 -0
  332. package/dist/types/transport/node/helpers.d.ts +3 -0
  333. package/dist/types/transport/node/mex/argo-decoder.d.ts +11 -0
  334. package/dist/types/transport/node/mex/client.d.ts +18 -0
  335. package/dist/types/transport/node/mex/persist-ids.d.ts +14 -0
  336. package/dist/types/transport/noise/WaMobileClientPayload.d.ts +29 -0
  337. package/dist/types/transport/noise/WaNoiseCert.d.ts +7 -1
  338. package/dist/types/transport/noise/WaNoiseSession.d.ts +1 -0
  339. package/dist/types/transport/types.d.ts +8 -0
  340. package/package.json +6 -4
  341. package/dist/auth/pairing/constants.js +0 -5
  342. package/dist/client/connection/WaKeyShareCoordinator.js +0 -63
  343. package/dist/esm/auth/pairing/constants.js +0 -2
  344. package/dist/esm/client/connection/WaKeyShareCoordinator.js +0 -59
  345. package/dist/esm/transport/node/builders/index.js +0 -11
  346. package/dist/transport/node/builders/index.js +0 -51
  347. package/dist/types/auth/flow/WaAuthCredentialsFlow.d.ts +0 -14
  348. package/dist/types/auth/pairing/constants.d.ts +0 -2
  349. package/dist/types/client/connection/WaKeyShareCoordinator.d.ts +0 -14
  350. package/dist/types/transport/node/builders/index.d.ts +0 -11
  351. /package/dist/appstate/{WaAppStateSyncResponseParser.js → response-parser.js} +0 -0
@@ -1,14 +1,24 @@
1
- import { resolveCleanupIntervalMs } from '../../../util/collections.js';
2
- const DEFAULT_RETRY_TTL_MS = 60 * 1000;
1
+ import { resolvePositive } from '../../../util/coercion.js';
2
+ import { resolveCleanupIntervalMs, setBoundedMapEntry } from '../../../util/collections.js';
3
+ const DEFAULTS = Object.freeze({
4
+ ttlMs: 60 * 1000,
5
+ maxOutboundMessages: 10000,
6
+ maxInboundCounters: 20000
7
+ });
3
8
  export class WaRetryMemoryStore {
4
- constructor(ttlMs = DEFAULT_RETRY_TTL_MS) {
9
+ constructor(ttlMs = DEFAULTS.ttlMs, options = {}) {
10
+ if (!Number.isFinite(ttlMs) || ttlMs <= 0) {
11
+ throw new Error('retry ttlMs must be a positive finite number');
12
+ }
5
13
  this.outboundMessages = new Map();
6
14
  this.eligibleSets = new Map();
7
15
  this.inboundCounters = new Map();
8
16
  this.ttlMs = ttlMs;
17
+ this.maxOutboundMessages = resolvePositive(options.maxOutboundMessages, DEFAULTS.maxOutboundMessages, 'WaRetryMemoryStoreOptions.maxOutboundMessages');
18
+ this.maxInboundCounters = resolvePositive(options.maxInboundCounters, DEFAULTS.maxInboundCounters, 'WaRetryMemoryStoreOptions.maxInboundCounters');
9
19
  this.cleanupTimer = setInterval(() => {
10
20
  void this.cleanupExpired(Date.now());
11
- }, resolveCleanupIntervalMs(ttlMs));
21
+ }, resolveCleanupIntervalMs(this.ttlMs));
12
22
  this.cleanupTimer.unref();
13
23
  }
14
24
  getTtlMs() {
@@ -54,7 +64,7 @@ export class WaRetryMemoryStore {
54
64
  return { eligible: true, delivered: false };
55
65
  }
56
66
  async upsertOutboundMessage(record) {
57
- this.outboundMessages.set(record.messageId, {
67
+ const storedRecord = {
58
68
  ...record,
59
69
  eligibleRequesterDeviceJids: record.eligibleRequesterDeviceJids
60
70
  ? [...record.eligibleRequesterDeviceJids]
@@ -62,6 +72,9 @@ export class WaRetryMemoryStore {
62
72
  deliveredRequesterDeviceJids: record.deliveredRequesterDeviceJids
63
73
  ? [...record.deliveredRequesterDeviceJids]
64
74
  : undefined
75
+ };
76
+ setBoundedMapEntry(this.outboundMessages, record.messageId, storedRecord, this.maxOutboundMessages, (messageId) => {
77
+ this.eligibleSets.delete(messageId);
65
78
  });
66
79
  if (record.eligibleRequesterDeviceJids && record.eligibleRequesterDeviceJids.length > 0) {
67
80
  this.eligibleSets.set(record.messageId, new Set(record.eligibleRequesterDeviceJids));
@@ -83,11 +96,13 @@ export class WaRetryMemoryStore {
83
96
  if (!current) {
84
97
  return;
85
98
  }
86
- this.outboundMessages.set(messageId, {
99
+ setBoundedMapEntry(this.outboundMessages, messageId, {
87
100
  ...current,
88
101
  state,
89
102
  updatedAtMs,
90
103
  expiresAtMs
104
+ }, this.maxOutboundMessages, (evictedMessageId) => {
105
+ this.eligibleSets.delete(evictedMessageId);
91
106
  });
92
107
  }
93
108
  async markOutboundRequesterDelivered(messageId, requesterDeviceJid, updatedAtMs, expiresAtMs) {
@@ -97,21 +112,20 @@ export class WaRetryMemoryStore {
97
112
  }
98
113
  const delivered = new Set(current.deliveredRequesterDeviceJids ?? []);
99
114
  delivered.add(requesterDeviceJid);
100
- this.outboundMessages.set(messageId, {
115
+ setBoundedMapEntry(this.outboundMessages, messageId, {
101
116
  ...current,
102
117
  deliveredRequesterDeviceJids: Array.from(delivered),
103
118
  updatedAtMs,
104
119
  expiresAtMs
120
+ }, this.maxOutboundMessages, (evictedMessageId) => {
121
+ this.eligibleSets.delete(evictedMessageId);
105
122
  });
106
123
  }
107
124
  async incrementInboundCounter(messageId, requesterJid, _updatedAtMs, expiresAtMs) {
108
125
  const key = this.counterKey(messageId, requesterJid);
109
126
  const current = this.inboundCounters.get(key);
110
127
  const count = current ? current.count + 1 : 1;
111
- this.inboundCounters.set(key, {
112
- count,
113
- expiresAtMs
114
- });
128
+ setBoundedMapEntry(this.inboundCounters, key, { count, expiresAtMs }, this.maxInboundCounters);
115
129
  return count;
116
130
  }
117
131
  async cleanupExpired(nowMs) {
@@ -0,0 +1,45 @@
1
+ import { signalAddressKey } from '../../../protocol/jid.js';
2
+ import { resolvePositive } from '../../../util/coercion.js';
3
+ import { setBoundedMapEntry } from '../../../util/collections.js';
4
+ const DEFAULT_MAX_SESSIONS = 8192;
5
+ export class WaSessionMemoryStore {
6
+ constructor(options = {}) {
7
+ this.signalSessions = new Map();
8
+ this.maxSessions = resolvePositive(options.maxSessions, DEFAULT_MAX_SESSIONS, 'WaSessionMemoryStoreOptions.maxSessions');
9
+ }
10
+ async hasSession(address) {
11
+ return this.signalSessions.has(signalAddressKey(address));
12
+ }
13
+ async hasSessions(addresses) {
14
+ const result = new Array(addresses.length);
15
+ for (let i = 0; i < addresses.length; i += 1) {
16
+ result[i] = this.signalSessions.has(signalAddressKey(addresses[i]));
17
+ }
18
+ return result;
19
+ }
20
+ async getSession(address) {
21
+ return this.signalSessions.get(signalAddressKey(address)) ?? null;
22
+ }
23
+ async getSessionsBatch(addresses) {
24
+ const result = new Array(addresses.length);
25
+ for (let i = 0; i < addresses.length; i += 1) {
26
+ result[i] = this.signalSessions.get(signalAddressKey(addresses[i])) ?? null;
27
+ }
28
+ return result;
29
+ }
30
+ async setSession(address, session) {
31
+ setBoundedMapEntry(this.signalSessions, signalAddressKey(address), session, this.maxSessions);
32
+ }
33
+ async setSessionsBatch(entries) {
34
+ for (let index = 0; index < entries.length; index += 1) {
35
+ const entry = entries[index];
36
+ setBoundedMapEntry(this.signalSessions, signalAddressKey(entry.address), entry.session, this.maxSessions);
37
+ }
38
+ }
39
+ async deleteSession(address) {
40
+ this.signalSessions.delete(signalAddressKey(address));
41
+ }
42
+ async clear() {
43
+ this.signalSessions.clear();
44
+ }
45
+ }
@@ -1,25 +1,8 @@
1
- import { signalAddressKey } from '../../../protocol/jid.js';
2
- import { resolvePositive } from '../../../util/coercion.js';
3
- import { setBoundedMapEntry } from '../../../util/collections.js';
4
- const DEFAULT_SIGNAL_STORE_LIMITS = Object.freeze({
5
- preKeys: 4096,
6
- sessions: 8192,
7
- remoteIdentities: 8192
8
- });
9
1
  export class WaSignalMemoryStore {
10
- constructor(options = {}) {
2
+ constructor() {
11
3
  this.registrationInfo = null;
12
4
  this.signedPreKey = null;
13
5
  this.signedPreKeyRotationTs = null;
14
- this.preKeys = new Map();
15
- this.uploadedPreKeys = new Set();
16
- this.serverHasPreKeys = false;
17
- this.signalSessions = new Map();
18
- this.remoteIdentities = new Map();
19
- this.nextPreKeyId = 1;
20
- this.maxPreKeys = resolvePositive(options.maxPreKeys, DEFAULT_SIGNAL_STORE_LIMITS.preKeys, 'WaSignalMemoryStoreOptions.maxPreKeys');
21
- this.maxSessions = resolvePositive(options.maxSessions, DEFAULT_SIGNAL_STORE_LIMITS.sessions, 'WaSignalMemoryStoreOptions.maxSessions');
22
- this.maxRemoteIdentities = resolvePositive(options.maxRemoteIdentities, DEFAULT_SIGNAL_STORE_LIMITS.remoteIdentities, 'WaSignalMemoryStoreOptions.maxRemoteIdentities');
23
6
  }
24
7
  async getRegistrationInfo() {
25
8
  return this.registrationInfo;
@@ -45,155 +28,9 @@ export class WaSignalMemoryStore {
45
28
  async getSignedPreKeyRotationTs() {
46
29
  return this.signedPreKeyRotationTs;
47
30
  }
48
- async putPreKey(record) {
49
- setBoundedMapEntry(this.preKeys, record.keyId, record, this.maxPreKeys, (keyId) => {
50
- this.uploadedPreKeys.delete(keyId);
51
- });
52
- if (record.keyId >= this.nextPreKeyId) {
53
- this.nextPreKeyId = record.keyId + 1;
54
- }
55
- }
56
- async getOrGenPreKeys(count, generator) {
57
- if (!Number.isSafeInteger(count) || count <= 0) {
58
- throw new Error(`invalid prekey count: ${count}`);
59
- }
60
- const available = [];
61
- const availableKeyIds = [];
62
- for (const keyId of this.preKeys.keys()) {
63
- if (!this.uploadedPreKeys.has(keyId)) {
64
- availableKeyIds.push(keyId);
65
- }
66
- }
67
- availableKeyIds.sort((left, right) => left - right);
68
- for (let index = 0; index < availableKeyIds.length; index += 1) {
69
- const keyId = availableKeyIds[index];
70
- const record = this.preKeys.get(keyId);
71
- if (!record) {
72
- continue;
73
- }
74
- available.push(record);
75
- if (available.length >= count) {
76
- return available;
77
- }
78
- }
79
- while (available.length < count) {
80
- const record = await generator(this.nextPreKeyId++);
81
- setBoundedMapEntry(this.preKeys, record.keyId, record, this.maxPreKeys, (keyId) => {
82
- this.uploadedPreKeys.delete(keyId);
83
- });
84
- available.push(record);
85
- }
86
- return available;
87
- }
88
- async getPreKeyById(keyId) {
89
- return this.preKeys.get(keyId) ?? null;
90
- }
91
- async getPreKeysById(keyIds) {
92
- const result = new Array(keyIds.length);
93
- for (let i = 0; i < keyIds.length; i += 1) {
94
- result[i] = this.preKeys.get(keyIds[i]) ?? null;
95
- }
96
- return result;
97
- }
98
- async consumePreKeyById(keyId) {
99
- const record = this.preKeys.get(keyId) ?? null;
100
- if (!record) {
101
- return null;
102
- }
103
- this.preKeys.delete(keyId);
104
- this.uploadedPreKeys.delete(keyId);
105
- return record;
106
- }
107
- async getOrGenSinglePreKey(generator) {
108
- const preKeys = await this.getOrGenPreKeys(1, generator);
109
- return preKeys[0];
110
- }
111
- async markKeyAsUploaded(keyId) {
112
- if (keyId < 0 || keyId >= this.nextPreKeyId) {
113
- throw new Error(`prekey ${keyId} is out of boundary`);
114
- }
115
- for (const candidate of this.preKeys.keys()) {
116
- if (candidate <= keyId) {
117
- this.addUploadedPreKey(candidate);
118
- }
119
- }
120
- }
121
- async setServerHasPreKeys(value) {
122
- this.serverHasPreKeys = value;
123
- }
124
- async getServerHasPreKeys() {
125
- return this.serverHasPreKeys;
126
- }
127
- async getSignalMeta() {
128
- return {
129
- serverHasPreKeys: this.serverHasPreKeys,
130
- signedPreKeyRotationTs: this.signedPreKeyRotationTs,
131
- registrationInfo: this.registrationInfo,
132
- signedPreKey: this.signedPreKey
133
- };
134
- }
135
- async hasSession(address) {
136
- return this.signalSessions.has(signalAddressKey(address));
137
- }
138
- async hasSessions(addresses) {
139
- const result = new Array(addresses.length);
140
- for (let i = 0; i < addresses.length; i += 1) {
141
- result[i] = this.signalSessions.has(signalAddressKey(addresses[i]));
142
- }
143
- return result;
144
- }
145
- async getSession(address) {
146
- return this.signalSessions.get(signalAddressKey(address)) ?? null;
147
- }
148
- async getSessionsBatch(addresses) {
149
- const result = new Array(addresses.length);
150
- for (let i = 0; i < addresses.length; i += 1) {
151
- result[i] = this.signalSessions.get(signalAddressKey(addresses[i])) ?? null;
152
- }
153
- return result;
154
- }
155
- async setSession(address, session) {
156
- setBoundedMapEntry(this.signalSessions, signalAddressKey(address), session, this.maxSessions);
157
- }
158
- async setSessionsBatch(entries) {
159
- for (let index = 0; index < entries.length; index += 1) {
160
- const entry = entries[index];
161
- setBoundedMapEntry(this.signalSessions, signalAddressKey(entry.address), entry.session, this.maxSessions);
162
- }
163
- }
164
- async deleteSession(address) {
165
- this.signalSessions.delete(signalAddressKey(address));
166
- }
167
- async getRemoteIdentity(address) {
168
- return this.remoteIdentities.get(signalAddressKey(address)) ?? null;
169
- }
170
- async getRemoteIdentities(addresses) {
171
- const result = new Array(addresses.length);
172
- for (let i = 0; i < addresses.length; i += 1) {
173
- result[i] = this.remoteIdentities.get(signalAddressKey(addresses[i])) ?? null;
174
- }
175
- return result;
176
- }
177
- async setRemoteIdentity(address, identityKey) {
178
- setBoundedMapEntry(this.remoteIdentities, signalAddressKey(address), identityKey, this.maxRemoteIdentities);
179
- }
180
- async setRemoteIdentities(entries) {
181
- for (const entry of entries) {
182
- setBoundedMapEntry(this.remoteIdentities, signalAddressKey(entry.address), entry.identityKey, this.maxRemoteIdentities);
183
- }
184
- }
185
31
  async clear() {
186
32
  this.registrationInfo = null;
187
33
  this.signedPreKey = null;
188
34
  this.signedPreKeyRotationTs = null;
189
- this.preKeys.clear();
190
- this.uploadedPreKeys.clear();
191
- this.serverHasPreKeys = false;
192
- this.signalSessions.clear();
193
- this.remoteIdentities.clear();
194
- this.nextPreKeyId = 1;
195
- }
196
- addUploadedPreKey(keyId) {
197
- this.uploadedPreKeys.add(keyId);
198
35
  }
199
36
  }
@@ -3,8 +3,7 @@ import { BoundedTaskQueue, BoundedTaskQueueFullError } from '../infra/perf/Bound
3
3
  import { WA_DEFAULTS } from '../protocol/constants.js';
4
4
  import { WaNoiseSession } from './noise/WaNoiseSession.js';
5
5
  import { WaWebSocket } from './WaWebSocket.js';
6
- import { bytesToBase64UrlSafe } from '../util/bytes.js';
7
- import { EMPTY_BYTES } from '../util/bytes.js';
6
+ import { bytesToBase64UrlSafe, EMPTY_BYTES } from '../util/bytes.js';
8
7
  import { toError } from '../util/primitives.js';
9
8
  const WA_FRAME_HANDLER_QUEUE_MAX_SIZE = 4096;
10
9
  const WA_FRAME_HANDLER_MAX_CONCURRENCY = 8;
@@ -29,7 +28,9 @@ export class WaComms {
29
28
  protocols: this.config.protocols,
30
29
  dispatcher: this.config.dispatcher,
31
30
  agent: this.config.agent,
32
- timeoutIntervalMs: this.config.timeoutIntervalMs
31
+ headers: this.config.headers,
32
+ timeoutIntervalMs: this.config.timeoutIntervalMs,
33
+ rawWebSocketConstructor: this.config.rawWebSocketConstructor
33
34
  }, logger);
34
35
  this.socket.setHandlers({
35
36
  onOpen: async () => {
@@ -75,7 +75,8 @@ export class WaWebSocket {
75
75
  });
76
76
  this.socketUrls = resolveSocketUrls(config);
77
77
  this.logger = logger;
78
- this.webSocketCtor = resolveWebSocketConstructor();
78
+ this.webSocketCtor = config.rawWebSocketConstructor ?? resolveWebSocketConstructor();
79
+ this.customWebSocketCtor = Boolean(config.rawWebSocketConstructor);
79
80
  this.socketRuntime = resolveSocketRuntime();
80
81
  this.connectingSockets = new Set();
81
82
  this.handlers = {};
@@ -411,6 +412,13 @@ export class WaWebSocket {
411
412
  const headers = this.config.headers;
412
413
  const dispatcher = this.config.dispatcher;
413
414
  const agent = this.config.agent;
415
+ if (this.customWebSocketCtor) {
416
+ return new this.webSocketCtor(url, this.config.protocols, {
417
+ headers,
418
+ dispatcher,
419
+ agent
420
+ });
421
+ }
414
422
  let hasHeaders = false;
415
423
  if (headers) {
416
424
  for (const key in headers) {
@@ -1,7 +1,13 @@
1
+ export { decodeBinaryNode, decodeBinaryNodeStanza, encodeBinaryNode, encodeBinaryNodeStanza } from './binary/index.js';
1
2
  export { isProxyAgent, isProxyDispatcher, isProxyTransport, toProxyAgent, toProxyDispatcher } from './proxy.js';
2
3
  export { WaComms } from './WaComms.js';
4
+ export { verifyNoiseCertificateChain } from './noise/WaNoiseCert.js';
5
+ export { WaNoiseHandshake } from './noise/WaNoiseHandshake.js';
6
+ export { WaNoiseSocket } from './noise/WaNoiseSocket.js';
3
7
  export { WaWebSocket } from './WaWebSocket.js';
4
8
  export { WaKeepAlive } from './keepalive/WaKeepAlive.js';
5
9
  export { WaNodeOrchestrator } from './node/WaNodeOrchestrator.js';
6
10
  export { WaNodeTransport } from './node/WaNodeTransport.js';
11
+ export { WaMobileTcpSocket, WaMobileTcpSocketCtor } from './node/WaMobileTcpSocket.js';
12
+ export { buildMobileLoginPayload } from './noise/WaMobileClientPayload.js';
7
13
  export { assertIqResult, buildIqNode, parseIqError, queryWithContext } from './node/query.js';
@@ -8,7 +8,8 @@ export class WaKeepAlive {
8
8
  this.logger = options.logger;
9
9
  this.nodeOrchestrator = options.nodeOrchestrator;
10
10
  this.getCommsFn = options.getComms;
11
- this.intervalMs = options.intervalMs ?? WA_DEFAULTS.HEALTH_CHECK_INTERVAL_MS;
11
+ this.baseIntervalMs = options.intervalMs ?? WA_DEFAULTS.HEALTH_CHECK_INTERVAL_MS;
12
+ this.getIntervalMs = options.getIntervalMs;
12
13
  this.timeoutMs = options.timeoutMs ?? WA_DEFAULTS.DEAD_SOCKET_TIMEOUT_MS;
13
14
  this.hostDomain = options.hostDomain ?? WA_DEFAULTS.HOST_DOMAIN;
14
15
  this.jitterRatio = this.normalizeJitterRatio(options.jitterRatio);
@@ -19,7 +20,7 @@ export class WaKeepAlive {
19
20
  }
20
21
  start() {
21
22
  this.logger.info('keepalive start', {
22
- intervalMs: this.intervalMs,
23
+ intervalMs: this.resolveIntervalMs(),
23
24
  timeoutMs: this.timeoutMs,
24
25
  jitterRatio: this.jitterRatio,
25
26
  minJitterMs: this.minJitterMs
@@ -48,7 +49,7 @@ export class WaKeepAlive {
48
49
  this.logger.trace('keepalive scheduled', {
49
50
  generation,
50
51
  inMs: nextDelayMs,
51
- baseIntervalMs: this.intervalMs
52
+ baseIntervalMs: this.resolveIntervalMs()
52
53
  });
53
54
  }
54
55
  async run(generation) {
@@ -110,20 +111,28 @@ export class WaKeepAlive {
110
111
  const normalized = value;
111
112
  return Math.min(Math.max(normalized, 0), KEEPALIVE_MAX_JITTER_RATIO);
112
113
  }
114
+ resolveIntervalMs() {
115
+ const candidate = this.getIntervalMs?.() ?? this.baseIntervalMs;
116
+ if (!Number.isFinite(candidate) || candidate <= 0) {
117
+ return this.baseIntervalMs;
118
+ }
119
+ return candidate;
120
+ }
113
121
  computeNextDelayMs() {
114
- if (this.intervalMs <= 0) {
122
+ const intervalMs = this.resolveIntervalMs();
123
+ if (intervalMs <= 0) {
115
124
  return 0;
116
125
  }
117
126
  if (this.jitterRatio <= 0 && this.minJitterMs <= 0) {
118
- return this.intervalMs;
127
+ return intervalMs;
119
128
  }
120
- const ratioJitterMs = Math.floor(this.intervalMs * this.jitterRatio);
129
+ const ratioJitterMs = Math.floor(intervalMs * this.jitterRatio);
121
130
  const jitterWindowMs = Math.max(this.minJitterMs, ratioJitterMs);
122
131
  if (jitterWindowMs <= 0) {
123
- return this.intervalMs;
132
+ return intervalMs;
124
133
  }
125
134
  const offsetMs = Math.floor(Math.random() * (jitterWindowMs * 2 + 1) - jitterWindowMs);
126
- return Math.max(1, this.intervalMs + offsetMs);
135
+ return Math.max(1, intervalMs + offsetMs);
127
136
  }
128
137
  clearTimer() {
129
138
  if (!this.timer) {
@@ -0,0 +1,114 @@
1
+ import { connect as netConnect } from 'node:net';
2
+ import { WA_READY_STATES } from '../../protocol/constants.js';
3
+ import { TEXT_ENCODER } from '../../util/bytes.js';
4
+ export class WaMobileTcpSocket {
5
+ constructor(url, _protocols, _options) {
6
+ this.binaryType = 'arraybuffer';
7
+ this.readyState = WA_READY_STATES.CONNECTING;
8
+ this.onopen = null;
9
+ this.onclose = null;
10
+ this.onerror = null;
11
+ this.onmessage = null;
12
+ this.closedCode = 1000;
13
+ this.closedReason = '';
14
+ this.closedClean = true;
15
+ this.forceCloseTimer = null;
16
+ const { host, port } = parseTcpUrl(url);
17
+ this.socket = netConnect({ host, port });
18
+ this.socket.on('connect', () => {
19
+ if (this.readyState !== WA_READY_STATES.CONNECTING)
20
+ return;
21
+ this.readyState = WA_READY_STATES.OPEN;
22
+ this.onopen?.({});
23
+ });
24
+ this.socket.on('data', (chunk) => {
25
+ if (!this.onmessage || this.readyState !== WA_READY_STATES.OPEN)
26
+ return;
27
+ const copy = new Uint8Array(chunk.byteLength);
28
+ copy.set(chunk);
29
+ this.onmessage({ data: copy });
30
+ });
31
+ this.socket.on('error', (err) => {
32
+ this.closedClean = false;
33
+ this.closedReason = err.message;
34
+ this.onerror?.({ reason: err.message });
35
+ });
36
+ this.socket.on('close', (hadError) => {
37
+ this.readyState = WA_READY_STATES.CLOSED;
38
+ if (this.forceCloseTimer) {
39
+ clearTimeout(this.forceCloseTimer);
40
+ this.forceCloseTimer = null;
41
+ }
42
+ if (hadError)
43
+ this.closedClean = false;
44
+ this.onclose?.({
45
+ code: this.closedCode,
46
+ reason: this.closedReason,
47
+ wasClean: this.closedClean
48
+ });
49
+ });
50
+ }
51
+ send(data) {
52
+ if (this.readyState !== WA_READY_STATES.OPEN) {
53
+ throw new Error('WaMobileTcpSocket: send() called on non-OPEN socket');
54
+ }
55
+ let bytes;
56
+ if (typeof data === 'string') {
57
+ bytes = TEXT_ENCODER.encode(data);
58
+ }
59
+ else if (data instanceof Uint8Array) {
60
+ bytes = data;
61
+ }
62
+ else {
63
+ bytes = new Uint8Array(data);
64
+ }
65
+ this.socket.write(bytes);
66
+ }
67
+ close(code, reason) {
68
+ if (this.readyState === WA_READY_STATES.CLOSED)
69
+ return;
70
+ this.readyState = WA_READY_STATES.CLOSING;
71
+ this.closedCode = code ?? 1000;
72
+ this.closedReason = reason ?? '';
73
+ this.socket.end();
74
+ this.forceCloseTimer = setTimeout(() => {
75
+ this.forceCloseTimer = null;
76
+ if (this.readyState !== WA_READY_STATES.CLOSED) {
77
+ this.socket.destroy();
78
+ }
79
+ }, 5000);
80
+ this.forceCloseTimer.unref();
81
+ }
82
+ }
83
+ function parseTcpUrl(url) {
84
+ let work = url;
85
+ if (work.startsWith('tcp://')) {
86
+ work = work.slice('tcp://'.length);
87
+ }
88
+ const queryIdx = work.indexOf('?');
89
+ if (queryIdx >= 0) {
90
+ work = work.slice(0, queryIdx);
91
+ }
92
+ const slash = work.indexOf('/');
93
+ if (slash >= 0) {
94
+ work = work.slice(0, slash);
95
+ }
96
+ const colon = work.lastIndexOf(':');
97
+ const host = colon === -1 ? work : work.slice(0, colon);
98
+ if (host.length === 0) {
99
+ throw new Error(`WaMobileTcpSocket: invalid host in ${JSON.stringify(url)}`);
100
+ }
101
+ if (colon === -1) {
102
+ return { host, port: 443 };
103
+ }
104
+ const portText = work.slice(colon + 1);
105
+ if (!/^\d+$/.test(portText)) {
106
+ throw new Error(`WaMobileTcpSocket: invalid port in ${JSON.stringify(url)}`);
107
+ }
108
+ const port = Number(portText);
109
+ if (port < 1 || port > 65535) {
110
+ throw new Error(`WaMobileTcpSocket: port out of range in ${JSON.stringify(url)}`);
111
+ }
112
+ return { host, port };
113
+ }
114
+ export const WaMobileTcpSocketCtor = WaMobileTcpSocket;
@@ -1,12 +1,13 @@
1
1
  import { WA_DEFAULTS, WA_IQ_TYPES, WA_NODE_TAGS, WA_XMLNS } from '../../protocol/constants.js';
2
2
  import { toError } from '../../util/primitives.js';
3
- import { createNodeIdGenerator } from './helpers.js';
3
+ import { createMobileNodeIdGenerator, createNodeIdGenerator } from './helpers.js';
4
4
  export class WaNodeOrchestrator {
5
5
  constructor(options) {
6
6
  this.logger = options.logger;
7
7
  this.sendNodeFn = options.sendNode;
8
8
  this.defaultTimeoutMs = options.defaultTimeoutMs ?? WA_DEFAULTS.NODE_QUERY_TIMEOUT_MS;
9
9
  this.hostDomain = options.hostDomain ?? WA_DEFAULTS.HOST_DOMAIN;
10
+ this.mobileIqIdFormat = options.mobileIqIdFormat === true;
10
11
  this.idGenerator = null;
11
12
  this.idGeneratorReady = null;
12
13
  this.pendingQueries = new Map();
@@ -69,12 +70,12 @@ export class WaNodeOrchestrator {
69
70
  this.logger.debug('auto-responded to ping iq', { id: node.attrs.id, xmlns });
70
71
  return true;
71
72
  }
72
- async sendNode(node) {
73
- const outbound = await this.withAutoId(node);
73
+ async sendNode(node, autoId = true) {
74
+ const outbound = autoId ? await this.withAutoId(node) : node;
74
75
  await this.sendNodeFn(outbound);
75
76
  }
76
- async query(node, timeoutMs = this.defaultTimeoutMs) {
77
- const outbound = await this.withAutoId(node);
77
+ async query(node, timeoutMs = this.defaultTimeoutMs, options = {}) {
78
+ const outbound = await this.withAutoId(node, options.useSystemId === true);
78
79
  const id = outbound.attrs.id;
79
80
  if (!id) {
80
81
  throw new Error('query node id is required');
@@ -110,12 +111,13 @@ export class WaNodeOrchestrator {
110
111
  });
111
112
  });
112
113
  }
113
- async withAutoId(node) {
114
+ async withAutoId(node, useSystemId = false) {
114
115
  if (node.attrs.id) {
115
116
  return node;
116
117
  }
117
- const generatedId = (await this.getIdGenerator()).next();
118
- this.logger.trace('generated stanza id', { id: generatedId });
118
+ const generator = await this.getIdGenerator();
119
+ const generatedId = useSystemId && generator.nextSystem ? generator.nextSystem() : generator.next();
120
+ this.logger.trace('generated stanza id', { id: generatedId, system: useSystemId });
119
121
  return {
120
122
  ...node,
121
123
  attrs: {
@@ -128,6 +130,13 @@ export class WaNodeOrchestrator {
128
130
  if (this.idGenerator) {
129
131
  return this.idGenerator;
130
132
  }
133
+ if (this.mobileIqIdFormat) {
134
+ this.idGenerator = createMobileNodeIdGenerator();
135
+ this.logger.debug('generated stanza prefix (mobile)', {
136
+ prefix: this.idGenerator.prefix
137
+ });
138
+ return this.idGenerator;
139
+ }
131
140
  if (!this.idGeneratorReady) {
132
141
  this.idGeneratorReady = createNodeIdGenerator();
133
142
  }
@@ -0,0 +1,20 @@
1
+ import { WA_ABPROPS_PROTOCOL_VERSION } from '../../../protocol/abprops.js';
2
+ import { WA_DEFAULTS, WA_XMLNS } from '../../../protocol/constants.js';
3
+ import { buildIqNode } from '../../node/query.js';
4
+ export function buildGetAbPropsIq(options) {
5
+ const propsAttrs = {
6
+ protocol: WA_ABPROPS_PROTOCOL_VERSION
7
+ };
8
+ if (options?.hash) {
9
+ propsAttrs.hash = options.hash;
10
+ }
11
+ if (options?.refreshId !== undefined && options.refreshId !== null) {
12
+ propsAttrs.refresh_id = `${options.refreshId}`;
13
+ }
14
+ return buildIqNode('get', WA_DEFAULTS.HOST_DOMAIN, WA_XMLNS.ABPROPS, [
15
+ {
16
+ tag: 'props',
17
+ attrs: propsAttrs
18
+ }
19
+ ]);
20
+ }
@@ -0,0 +1,11 @@
1
+ import { WA_DEFAULTS } from '../../../protocol/defaults.js';
2
+ import { WA_XMLNS } from '../../../protocol/nodes.js';
3
+ import { buildIqNode } from '../../node/query.js';
4
+ export function buildRemoveCompanionDeviceIq(deviceJid, reason) {
5
+ return buildIqNode('set', WA_DEFAULTS.HOST_DOMAIN, WA_XMLNS.MD, [
6
+ {
7
+ tag: 'remove-companion-device',
8
+ attrs: { jid: deviceJid, reason }
9
+ }
10
+ ]);
11
+ }