zapo-js 0.1.1 → 0.2.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 (589) hide show
  1. package/README.md +20 -4
  2. package/dist/appstate/WaAppStateCrypto.js +19 -26
  3. package/dist/appstate/WaAppStateSyncClient.js +293 -181
  4. package/dist/appstate/WaAppStateSyncResponseParser.js +16 -5
  5. package/dist/appstate/constants.js +4 -3
  6. package/dist/appstate/{store/sqlite.js → encoding.js} +13 -8
  7. package/dist/appstate/index.js +8 -6
  8. package/dist/appstate/utils.js +9 -34
  9. package/dist/auth/WaAuthClient.js +43 -61
  10. package/dist/auth/flow/WaAuthCredentialsFlow.js +22 -15
  11. package/dist/auth/index.js +1 -8
  12. package/dist/auth/pairing/WaPairingCodeCrypto.js +6 -4
  13. package/dist/auth/pairing/WaPairingFlow.js +34 -26
  14. package/dist/auth/pairing/WaQrFlow.js +37 -24
  15. package/dist/client/WaClient.js +275 -324
  16. package/dist/client/WaClientFactory.js +500 -133
  17. package/dist/client/connection/WaConnectionManager.js +301 -0
  18. package/dist/client/connection/WaKeyShareCoordinator.js +63 -0
  19. package/dist/client/connection/WaReceiptQueue.js +51 -0
  20. package/dist/client/coordinators/WaAppStateMutationCoordinator.js +471 -0
  21. package/dist/client/coordinators/WaBusinessCoordinator.js +241 -0
  22. package/dist/client/coordinators/WaGroupCoordinator.js +30 -16
  23. package/dist/client/coordinators/WaIncomingNodeCoordinator.js +21 -27
  24. package/dist/client/coordinators/WaMessageDispatchCoordinator.js +439 -701
  25. package/dist/client/coordinators/WaPassiveTasksCoordinator.js +74 -31
  26. package/dist/client/coordinators/WaPrivacyCoordinator.js +134 -0
  27. package/dist/client/coordinators/WaProfileCoordinator.js +212 -0
  28. package/dist/client/coordinators/WaRetryCoordinator.js +242 -57
  29. package/dist/client/coordinators/WaStreamControlCoordinator.js +18 -11
  30. package/dist/client/coordinators/WaTrustedContactTokenCoordinator.js +166 -0
  31. package/dist/client/dirty.js +74 -48
  32. package/dist/client/events/chat.js +4 -3
  33. package/dist/client/events/devices.js +72 -0
  34. package/dist/client/events/group.js +62 -47
  35. package/dist/client/events/identity.js +22 -0
  36. package/dist/client/events/privacy-token.js +39 -0
  37. package/dist/client/history-sync.js +94 -63
  38. package/dist/client/incoming.js +60 -27
  39. package/dist/client/mailbox.js +24 -23
  40. package/dist/client/messages.js +107 -31
  41. package/dist/client/messaging/fanout.js +199 -0
  42. package/dist/client/messaging/key-protocol.js +130 -0
  43. package/dist/client/messaging/participants.js +193 -0
  44. package/dist/client/persistence/WriteBehindPersistence.js +129 -0
  45. package/dist/client/tokens/cs-token.js +50 -0
  46. package/dist/client/tokens/tc-token.js +25 -0
  47. package/dist/crypto/core/hkdf.js +3 -8
  48. package/dist/crypto/core/index.js +2 -5
  49. package/dist/crypto/core/keys.js +6 -7
  50. package/dist/crypto/core/nonce.js +2 -0
  51. package/dist/crypto/core/primitives.js +12 -23
  52. package/dist/crypto/core/random.js +26 -23
  53. package/dist/crypto/curves/Ed25519.js +7 -8
  54. package/dist/crypto/curves/X25519.js +38 -22
  55. package/dist/crypto/index.js +1 -3
  56. package/dist/crypto/math/constants.js +13 -36
  57. package/dist/crypto/math/edwards.js +171 -44
  58. package/dist/crypto/math/fe.js +706 -0
  59. package/dist/crypto/math/mod.js +10 -3
  60. package/dist/esm/appstate/WaAppStateCrypto.js +7 -14
  61. package/dist/esm/appstate/WaAppStateSyncClient.js +284 -172
  62. package/dist/esm/appstate/WaAppStateSyncResponseParser.js +17 -6
  63. package/dist/esm/appstate/constants.js +3 -2
  64. package/dist/esm/appstate/{store/sqlite.js → encoding.js} +13 -8
  65. package/dist/esm/appstate/index.js +2 -2
  66. package/dist/esm/appstate/utils.js +8 -30
  67. package/dist/esm/auth/WaAuthClient.js +43 -61
  68. package/dist/esm/auth/flow/WaAuthCredentialsFlow.js +22 -15
  69. package/dist/esm/auth/index.js +0 -3
  70. package/dist/esm/auth/pairing/WaPairingCodeCrypto.js +6 -4
  71. package/dist/esm/auth/pairing/WaPairingFlow.js +28 -20
  72. package/dist/esm/auth/pairing/WaQrFlow.js +37 -24
  73. package/dist/esm/client/WaClient.js +275 -324
  74. package/dist/esm/client/WaClientFactory.js +501 -134
  75. package/dist/esm/client/connection/WaConnectionManager.js +297 -0
  76. package/dist/esm/client/connection/WaKeyShareCoordinator.js +59 -0
  77. package/dist/esm/client/connection/WaReceiptQueue.js +47 -0
  78. package/dist/esm/client/coordinators/WaAppStateMutationCoordinator.js +467 -0
  79. package/dist/esm/client/coordinators/WaBusinessCoordinator.js +238 -0
  80. package/dist/esm/client/coordinators/WaGroupCoordinator.js +23 -9
  81. package/dist/esm/client/coordinators/WaIncomingNodeCoordinator.js +21 -27
  82. package/dist/esm/client/coordinators/WaMessageDispatchCoordinator.js +443 -705
  83. package/dist/esm/client/coordinators/WaPassiveTasksCoordinator.js +74 -31
  84. package/dist/esm/client/coordinators/WaPrivacyCoordinator.js +131 -0
  85. package/dist/esm/client/coordinators/WaProfileCoordinator.js +209 -0
  86. package/dist/esm/client/coordinators/WaRetryCoordinator.js +244 -59
  87. package/dist/esm/client/coordinators/WaStreamControlCoordinator.js +19 -12
  88. package/dist/esm/client/coordinators/WaTrustedContactTokenCoordinator.js +162 -0
  89. package/dist/esm/client/dirty.js +69 -43
  90. package/dist/esm/client/events/chat.js +4 -3
  91. package/dist/esm/client/events/devices.js +68 -0
  92. package/dist/esm/client/events/group.js +53 -39
  93. package/dist/esm/client/events/identity.js +19 -0
  94. package/dist/esm/client/events/privacy-token.js +36 -0
  95. package/dist/esm/client/history-sync.js +91 -60
  96. package/dist/esm/client/incoming.js +61 -28
  97. package/dist/esm/client/mailbox.js +24 -23
  98. package/dist/esm/client/messages.js +108 -32
  99. package/dist/esm/client/messaging/fanout.js +196 -0
  100. package/dist/esm/client/messaging/key-protocol.js +127 -0
  101. package/dist/esm/client/messaging/participants.js +190 -0
  102. package/dist/esm/client/persistence/WriteBehindPersistence.js +125 -0
  103. package/dist/esm/client/tokens/cs-token.js +46 -0
  104. package/dist/esm/client/tokens/tc-token.js +18 -0
  105. package/dist/esm/crypto/core/hkdf.js +3 -8
  106. package/dist/esm/crypto/core/index.js +2 -3
  107. package/dist/esm/crypto/core/keys.js +3 -4
  108. package/dist/esm/crypto/core/nonce.js +2 -0
  109. package/dist/esm/crypto/core/primitives.js +12 -22
  110. package/dist/esm/crypto/core/random.js +25 -23
  111. package/dist/esm/crypto/curves/Ed25519.js +4 -5
  112. package/dist/esm/crypto/curves/X25519.js +35 -19
  113. package/dist/esm/crypto/index.js +0 -1
  114. package/dist/esm/crypto/math/constants.js +12 -35
  115. package/dist/esm/crypto/math/edwards.js +174 -47
  116. package/dist/esm/crypto/math/fe.js +691 -0
  117. package/dist/esm/crypto/math/mod.js +10 -1
  118. package/dist/esm/index.js +1 -1
  119. package/dist/esm/infra/log/ConsoleLogger.js +18 -17
  120. package/dist/esm/infra/log/PinoLogger.js +15 -9
  121. package/dist/esm/infra/log/types.js +11 -1
  122. package/dist/esm/infra/perf/BackgroundQueue.js +478 -0
  123. package/dist/esm/infra/perf/BoundedTaskQueue.js +16 -18
  124. package/dist/esm/infra/perf/PromiseDedup.js +20 -0
  125. package/dist/esm/infra/perf/SharedExclusiveGate.js +109 -0
  126. package/dist/esm/infra/perf/StoreLock.js +77 -0
  127. package/dist/esm/media/WaMediaCrypto.js +96 -16
  128. package/dist/esm/media/WaMediaTransferClient.js +251 -91
  129. package/dist/esm/media/conn.js +10 -6
  130. package/dist/esm/media/constants.js +6 -2
  131. package/dist/esm/message/WaMessageClient.js +30 -32
  132. package/dist/esm/message/ack.js +6 -6
  133. package/dist/esm/message/addon-crypto.js +59 -0
  134. package/dist/esm/message/content.js +195 -9
  135. package/dist/esm/message/icdc.js +76 -0
  136. package/dist/esm/message/incoming.js +129 -122
  137. package/dist/esm/message/index.js +2 -0
  138. package/dist/esm/message/phash.js +3 -1
  139. package/dist/esm/message/reporting-token.js +425 -0
  140. package/dist/esm/message/use-case-secret.js +49 -0
  141. package/dist/esm/protocol/appstate.js +27 -0
  142. package/dist/esm/protocol/browser.js +10 -18
  143. package/dist/esm/protocol/constants.js +6 -3
  144. package/dist/esm/protocol/defaults.js +6 -0
  145. package/dist/esm/protocol/index.js +2 -11
  146. package/dist/esm/protocol/jid.js +133 -52
  147. package/dist/esm/protocol/media.js +3 -3
  148. package/dist/esm/protocol/message.js +61 -1
  149. package/dist/esm/protocol/nodes.js +4 -0
  150. package/dist/esm/protocol/notification.js +3 -1
  151. package/dist/esm/protocol/privacy-token.js +17 -0
  152. package/dist/esm/protocol/privacy.js +55 -0
  153. package/dist/esm/protocol/stream.js +26 -1
  154. package/dist/esm/protocol/usync.js +11 -0
  155. package/dist/esm/retry/codec.js +216 -0
  156. package/dist/esm/retry/constants.js +1 -1
  157. package/dist/esm/retry/index.js +3 -2
  158. package/dist/esm/retry/parse.js +88 -86
  159. package/dist/esm/retry/replay.js +54 -51
  160. package/dist/esm/retry/tracker.js +94 -0
  161. package/dist/esm/signal/api/SignalDeviceSyncApi.js +276 -92
  162. package/dist/esm/signal/api/SignalDigestSyncApi.js +17 -8
  163. package/dist/esm/signal/api/SignalIdentitySyncApi.js +67 -37
  164. package/dist/esm/signal/api/SignalMissingPreKeysSyncApi.js +86 -67
  165. package/dist/esm/signal/api/SignalRotateKeyApi.js +4 -2
  166. package/dist/esm/signal/api/SignalSessionSyncApi.js +36 -34
  167. package/dist/esm/signal/api/result-map.js +10 -0
  168. package/dist/esm/signal/constants.js +0 -4
  169. package/dist/esm/signal/crypto/WaAdvSignature.js +13 -9
  170. package/dist/esm/signal/{store/sqlite.js → encoding.js} +93 -60
  171. package/dist/esm/signal/group/SenderKeyChain.js +28 -23
  172. package/dist/esm/signal/group/SenderKeyCodec.js +5 -6
  173. package/dist/esm/signal/group/SenderKeyManager.js +144 -115
  174. package/dist/esm/signal/index.js +2 -0
  175. package/dist/esm/signal/registration/keygen.js +6 -2
  176. package/dist/esm/signal/registration/utils.js +1 -0
  177. package/dist/esm/signal/session/SignalProtocol.js +164 -53
  178. package/dist/esm/signal/session/SignalRatchet.js +24 -15
  179. package/dist/esm/signal/session/SignalSession.js +14 -9
  180. package/dist/esm/signal/session/resolver.js +221 -0
  181. package/dist/esm/store/contracts/privacy-token.store.js +1 -0
  182. package/dist/esm/store/createStore.js +100 -188
  183. package/dist/esm/store/index.js +1 -10
  184. package/dist/esm/store/locks/appstate.lock.js +26 -0
  185. package/dist/esm/store/locks/auth.lock.js +15 -0
  186. package/dist/esm/store/locks/contact.lock.js +20 -0
  187. package/dist/esm/store/locks/device-list.lock.js +20 -0
  188. package/dist/esm/store/locks/message.lock.js +21 -0
  189. package/dist/esm/store/locks/participants.lock.js +20 -0
  190. package/dist/esm/store/locks/privacy-token.lock.js +18 -0
  191. package/dist/esm/store/locks/retry.lock.js +29 -0
  192. package/dist/esm/store/locks/sender-key.lock.js +52 -0
  193. package/dist/esm/store/locks/signal.lock.js +63 -0
  194. package/dist/esm/store/locks/thread.lock.js +21 -0
  195. package/dist/esm/store/noop.store.js +4 -7
  196. package/dist/esm/store/providers/memory/appstate.store.js +38 -16
  197. package/dist/esm/store/providers/memory/contact.store.js +5 -0
  198. package/dist/esm/store/providers/memory/device-list.store.js +12 -34
  199. package/dist/esm/store/providers/memory/message.store.js +11 -5
  200. package/dist/esm/store/providers/memory/participants.store.js +1 -8
  201. package/dist/esm/store/providers/memory/privacy-token.store.js +43 -0
  202. package/dist/esm/store/providers/memory/retry.store.js +77 -2
  203. package/dist/esm/store/providers/memory/sender-key.store.js +11 -8
  204. package/dist/esm/store/providers/memory/signal.store.js +47 -18
  205. package/dist/esm/store/providers/memory/thread.store.js +5 -0
  206. package/dist/esm/transport/WaComms.js +28 -24
  207. package/dist/esm/transport/WaWebSocket.js +115 -18
  208. package/dist/esm/transport/binary/constants.js +0 -30
  209. package/dist/esm/transport/binary/decoder.js +8 -8
  210. package/dist/esm/transport/binary/encoder.js +10 -9
  211. package/dist/esm/transport/binary/index.js +0 -1
  212. package/dist/esm/transport/index.js +1 -0
  213. package/dist/esm/transport/keepalive/WaKeepAlive.js +2 -8
  214. package/dist/esm/transport/node/WaNodeOrchestrator.js +25 -21
  215. package/dist/esm/transport/node/WaNodeTransport.js +0 -3
  216. package/dist/esm/transport/node/builders/{accountSync.js → account-sync.js} +16 -36
  217. package/dist/esm/transport/node/builders/business.js +129 -0
  218. package/dist/esm/transport/node/builders/global.js +370 -0
  219. package/dist/esm/transport/node/builders/index.js +7 -3
  220. package/dist/esm/transport/node/builders/message.js +63 -230
  221. package/dist/esm/transport/node/builders/pairing.js +2 -27
  222. package/dist/esm/transport/node/builders/privacy-token.js +41 -0
  223. package/dist/esm/transport/node/builders/privacy.js +48 -0
  224. package/dist/esm/transport/node/builders/profile.js +70 -0
  225. package/dist/esm/transport/node/builders/retry.js +10 -22
  226. package/dist/esm/transport/node/builders/usync.js +45 -0
  227. package/dist/esm/transport/node/helpers.js +125 -5
  228. package/dist/esm/transport/node/usync.js +5 -0
  229. package/dist/esm/transport/node/xml.js +35 -14
  230. package/dist/esm/transport/noise/WaClientPayload.js +10 -10
  231. package/dist/esm/transport/noise/WaFrameCodec.js +48 -33
  232. package/dist/esm/transport/noise/WaNoiseCert.js +4 -7
  233. package/dist/esm/transport/noise/WaNoiseSession.js +77 -29
  234. package/dist/esm/transport/noise/WaNoiseSocket.js +8 -4
  235. package/dist/esm/transport/proxy.js +27 -0
  236. package/dist/esm/transport/stream/parse.js +17 -48
  237. package/dist/esm/util/bytes.js +67 -45
  238. package/dist/esm/util/coercion.js +6 -14
  239. package/dist/esm/util/index.js +5 -0
  240. package/dist/esm/util/primitives.js +40 -14
  241. package/dist/index.js +7 -1
  242. package/dist/infra/log/ConsoleLogger.js +18 -17
  243. package/dist/infra/log/PinoLogger.js +15 -9
  244. package/dist/infra/log/types.js +12 -0
  245. package/dist/infra/perf/BackgroundQueue.js +482 -0
  246. package/dist/infra/perf/BoundedTaskQueue.js +16 -18
  247. package/dist/infra/perf/PromiseDedup.js +24 -0
  248. package/dist/infra/perf/SharedExclusiveGate.js +113 -0
  249. package/dist/infra/perf/StoreLock.js +81 -0
  250. package/dist/media/WaMediaCrypto.js +95 -15
  251. package/dist/media/WaMediaTransferClient.js +284 -91
  252. package/dist/media/conn.js +10 -6
  253. package/dist/media/constants.js +6 -2
  254. package/dist/message/WaMessageClient.js +31 -33
  255. package/dist/message/ack.js +6 -6
  256. package/dist/message/addon-crypto.js +65 -0
  257. package/dist/message/content.js +198 -9
  258. package/dist/message/icdc.js +81 -0
  259. package/dist/message/incoming.js +127 -120
  260. package/dist/message/index.js +2 -0
  261. package/dist/message/phash.js +3 -1
  262. package/dist/message/reporting-token.js +429 -0
  263. package/dist/message/use-case-secret.js +55 -0
  264. package/dist/protocol/appstate.js +28 -1
  265. package/dist/protocol/browser.js +10 -18
  266. package/dist/protocol/constants.js +26 -1
  267. package/dist/protocol/defaults.js +6 -0
  268. package/dist/protocol/index.js +23 -42
  269. package/dist/protocol/jid.js +140 -52
  270. package/dist/protocol/media.js +3 -3
  271. package/dist/protocol/message.js +62 -2
  272. package/dist/protocol/nodes.js +4 -0
  273. package/dist/protocol/notification.js +3 -1
  274. package/dist/protocol/privacy-token.js +20 -0
  275. package/dist/protocol/privacy.js +58 -0
  276. package/dist/protocol/stream.js +27 -2
  277. package/dist/protocol/usync.js +14 -0
  278. package/dist/retry/codec.js +220 -0
  279. package/dist/retry/constants.js +1 -1
  280. package/dist/retry/index.js +7 -5
  281. package/dist/retry/parse.js +88 -85
  282. package/dist/retry/replay.js +52 -49
  283. package/dist/retry/tracker.js +97 -0
  284. package/dist/signal/api/SignalDeviceSyncApi.js +273 -89
  285. package/dist/signal/api/SignalDigestSyncApi.js +17 -8
  286. package/dist/signal/api/SignalIdentitySyncApi.js +66 -36
  287. package/dist/signal/api/SignalMissingPreKeysSyncApi.js +82 -63
  288. package/dist/signal/api/SignalRotateKeyApi.js +4 -2
  289. package/dist/signal/api/SignalSessionSyncApi.js +36 -34
  290. package/dist/signal/api/result-map.js +13 -0
  291. package/dist/signal/constants.js +1 -5
  292. package/dist/signal/crypto/WaAdvSignature.js +11 -7
  293. package/dist/signal/{store/sqlite.js → encoding.js} +94 -61
  294. package/dist/signal/group/SenderKeyChain.js +27 -22
  295. package/dist/signal/group/SenderKeyCodec.js +5 -6
  296. package/dist/signal/group/SenderKeyManager.js +144 -115
  297. package/dist/signal/index.js +15 -1
  298. package/dist/signal/registration/keygen.js +6 -2
  299. package/dist/signal/registration/utils.js +1 -0
  300. package/dist/signal/session/SignalProtocol.js +164 -53
  301. package/dist/signal/session/SignalRatchet.js +24 -15
  302. package/dist/signal/session/SignalSession.js +14 -9
  303. package/dist/signal/session/resolver.js +224 -0
  304. package/dist/store/contracts/privacy-token.store.js +2 -0
  305. package/dist/store/createStore.js +100 -188
  306. package/dist/store/index.js +15 -33
  307. package/dist/store/locks/appstate.lock.js +29 -0
  308. package/dist/store/locks/auth.lock.js +18 -0
  309. package/dist/store/locks/contact.lock.js +23 -0
  310. package/dist/store/locks/device-list.lock.js +23 -0
  311. package/dist/store/locks/message.lock.js +24 -0
  312. package/dist/store/locks/participants.lock.js +23 -0
  313. package/dist/store/locks/privacy-token.lock.js +21 -0
  314. package/dist/store/locks/retry.lock.js +32 -0
  315. package/dist/store/locks/sender-key.lock.js +55 -0
  316. package/dist/store/locks/signal.lock.js +66 -0
  317. package/dist/store/locks/thread.lock.js +24 -0
  318. package/dist/store/noop.store.js +4 -7
  319. package/dist/store/providers/memory/appstate.store.js +36 -14
  320. package/dist/store/providers/memory/contact.store.js +5 -0
  321. package/dist/store/providers/memory/device-list.store.js +12 -34
  322. package/dist/store/providers/memory/message.store.js +11 -5
  323. package/dist/store/providers/memory/participants.store.js +1 -8
  324. package/dist/store/providers/memory/privacy-token.store.js +47 -0
  325. package/dist/store/providers/memory/retry.store.js +77 -2
  326. package/dist/store/providers/memory/sender-key.store.js +14 -11
  327. package/dist/store/providers/memory/signal.store.js +54 -25
  328. package/dist/store/providers/memory/thread.store.js +5 -0
  329. package/dist/transport/WaComms.js +30 -26
  330. package/dist/transport/WaWebSocket.js +148 -18
  331. package/dist/transport/binary/constants.js +1 -31
  332. package/dist/transport/binary/decoder.js +8 -8
  333. package/dist/transport/binary/encoder.js +10 -9
  334. package/dist/transport/binary/index.js +0 -4
  335. package/dist/transport/index.js +7 -1
  336. package/dist/transport/keepalive/WaKeepAlive.js +1 -7
  337. package/dist/transport/node/WaNodeOrchestrator.js +25 -21
  338. package/dist/transport/node/WaNodeTransport.js +0 -3
  339. package/dist/transport/node/builders/{accountSync.js → account-sync.js} +15 -35
  340. package/dist/transport/node/builders/business.js +137 -0
  341. package/dist/transport/node/builders/global.js +375 -0
  342. package/dist/transport/node/builders/index.js +29 -17
  343. package/dist/transport/node/builders/message.js +64 -236
  344. package/dist/transport/node/builders/pairing.js +2 -29
  345. package/dist/transport/node/builders/privacy-token.js +46 -0
  346. package/dist/transport/node/builders/privacy.js +55 -0
  347. package/dist/transport/node/builders/profile.js +78 -0
  348. package/dist/transport/node/builders/retry.js +9 -21
  349. package/dist/transport/node/builders/usync.js +49 -0
  350. package/dist/transport/node/helpers.js +131 -4
  351. package/dist/transport/node/usync.js +8 -0
  352. package/dist/transport/node/xml.js +35 -14
  353. package/dist/transport/noise/WaClientPayload.js +13 -13
  354. package/dist/transport/noise/WaFrameCodec.js +47 -32
  355. package/dist/transport/noise/WaNoiseCert.js +5 -8
  356. package/dist/transport/noise/WaNoiseSession.js +77 -29
  357. package/dist/transport/noise/WaNoiseSocket.js +8 -4
  358. package/dist/transport/proxy.js +34 -0
  359. package/dist/transport/stream/parse.js +20 -52
  360. package/dist/types/appstate/WaAppStateCrypto.d.ts +0 -1
  361. package/dist/types/appstate/WaAppStateSyncClient.d.ts +5 -2
  362. package/dist/types/appstate/constants.d.ts +1 -0
  363. package/dist/types/appstate/encoding.d.ts +7 -0
  364. package/dist/types/appstate/index.d.ts +3 -3
  365. package/dist/types/appstate/utils.d.ts +0 -3
  366. package/dist/types/auth/WaAuthClient.d.ts +10 -12
  367. package/dist/types/auth/flow/WaAuthCredentialsFlow.d.ts +1 -1
  368. package/dist/types/auth/index.d.ts +0 -4
  369. package/dist/types/auth/pairing/WaQrFlow.d.ts +1 -1
  370. package/dist/types/auth/types.d.ts +7 -9
  371. package/dist/types/client/WaClient.d.ts +42 -25
  372. package/dist/types/client/WaClientFactory.d.ts +33 -26
  373. package/dist/types/client/connection/WaConnectionManager.d.ts +66 -0
  374. package/dist/types/client/connection/WaKeyShareCoordinator.d.ts +14 -0
  375. package/dist/types/client/connection/WaReceiptQueue.d.ts +13 -0
  376. package/dist/types/client/coordinators/WaAppStateMutationCoordinator.d.ts +46 -0
  377. package/dist/types/client/coordinators/WaBusinessCoordinator.d.ts +57 -0
  378. package/dist/types/client/coordinators/WaIncomingNodeCoordinator.d.ts +3 -2
  379. package/dist/types/client/coordinators/WaMessageDispatchCoordinator.d.ts +29 -38
  380. package/dist/types/client/coordinators/WaPassiveTasksCoordinator.d.ts +4 -0
  381. package/dist/types/client/coordinators/WaPrivacyCoordinator.d.ts +26 -0
  382. package/dist/types/client/coordinators/WaProfileCoordinator.d.ts +36 -0
  383. package/dist/types/client/coordinators/WaRetryCoordinator.d.ts +8 -0
  384. package/dist/types/client/coordinators/WaStreamControlCoordinator.d.ts +3 -2
  385. package/dist/types/client/coordinators/WaTrustedContactTokenCoordinator.d.ts +45 -0
  386. package/dist/types/client/dirty.d.ts +1 -0
  387. package/dist/types/client/events/devices.d.ts +20 -0
  388. package/dist/types/client/events/group.d.ts +2 -1
  389. package/dist/types/client/events/identity.d.ts +9 -0
  390. package/dist/types/client/events/privacy-token.d.ts +7 -0
  391. package/dist/types/client/history-sync.d.ts +9 -6
  392. package/dist/types/client/incoming.d.ts +3 -1
  393. package/dist/types/client/index.d.ts +1 -1
  394. package/dist/types/client/mailbox.d.ts +3 -5
  395. package/dist/types/client/messages.d.ts +1 -2
  396. package/dist/types/client/messaging/fanout.d.ts +14 -0
  397. package/dist/types/client/messaging/key-protocol.d.ts +18 -0
  398. package/dist/types/client/messaging/participants.d.ts +13 -0
  399. package/dist/types/client/persistence/WriteBehindPersistence.d.ts +34 -0
  400. package/dist/types/client/tokens/cs-token.d.ts +10 -0
  401. package/dist/types/client/tokens/tc-token.d.ts +5 -0
  402. package/dist/types/client/types.d.ts +75 -4
  403. package/dist/types/crypto/core/hkdf.d.ts +0 -6
  404. package/dist/types/crypto/core/index.d.ts +2 -3
  405. package/dist/types/crypto/core/nonce.d.ts +2 -0
  406. package/dist/types/crypto/core/primitives.d.ts +0 -1
  407. package/dist/types/crypto/core/random.d.ts +2 -7
  408. package/dist/types/crypto/index.d.ts +0 -1
  409. package/dist/types/crypto/math/constants.d.ts +4 -2
  410. package/dist/types/crypto/math/fe.d.ts +30 -0
  411. package/dist/types/crypto/math/mod.d.ts +0 -2
  412. package/dist/types/crypto/math/types.d.ts +11 -4
  413. package/dist/types/index.d.ts +5 -3
  414. package/dist/types/infra/log/ConsoleLogger.d.ts +2 -1
  415. package/dist/types/infra/log/PinoLogger.d.ts +1 -1
  416. package/dist/types/infra/log/types.d.ts +1 -0
  417. package/dist/types/infra/perf/BackgroundQueue.d.ts +58 -0
  418. package/dist/types/infra/perf/BoundedTaskQueue.d.ts +1 -1
  419. package/dist/types/infra/perf/PromiseDedup.d.ts +4 -0
  420. package/dist/types/infra/perf/SharedExclusiveGate.d.ts +17 -0
  421. package/dist/types/infra/perf/StoreLock.d.ts +10 -0
  422. package/dist/types/media/WaMediaCrypto.d.ts +3 -2
  423. package/dist/types/media/WaMediaTransferClient.d.ts +16 -15
  424. package/dist/types/media/constants.d.ts +1 -1
  425. package/dist/types/media/index.d.ts +1 -1
  426. package/dist/types/media/types.d.ts +15 -2
  427. package/dist/types/message/addon-crypto.d.ts +25 -0
  428. package/dist/types/message/content.d.ts +8 -0
  429. package/dist/types/message/icdc.d.ts +13 -0
  430. package/dist/types/message/index.d.ts +2 -0
  431. package/dist/types/message/reporting-token.d.ts +18 -0
  432. package/dist/types/message/types.d.ts +45 -6
  433. package/dist/types/message/use-case-secret.d.ts +20 -0
  434. package/dist/types/protocol/appstate.d.ts +47 -0
  435. package/dist/types/protocol/constants.d.ts +8 -3
  436. package/dist/types/protocol/defaults.d.ts +6 -0
  437. package/dist/types/protocol/index.d.ts +2 -11
  438. package/dist/types/protocol/jid.d.ts +22 -5
  439. package/dist/types/protocol/message.d.ts +60 -0
  440. package/dist/types/protocol/nodes.d.ts +4 -0
  441. package/dist/types/protocol/notification.d.ts +2 -0
  442. package/dist/types/protocol/privacy-token.d.ts +17 -0
  443. package/dist/types/protocol/privacy.d.ts +75 -0
  444. package/dist/types/protocol/stream.d.ts +30 -0
  445. package/dist/types/protocol/usync.d.ts +11 -0
  446. package/dist/types/retry/codec.d.ts +3 -0
  447. package/dist/types/retry/index.d.ts +4 -3
  448. package/dist/types/retry/parse.d.ts +5 -2
  449. package/dist/types/retry/replay.d.ts +0 -4
  450. package/dist/types/retry/tracker.d.ts +20 -0
  451. package/dist/types/retry/types.d.ts +10 -4
  452. package/dist/types/signal/api/SignalDeviceSyncApi.d.ts +15 -2
  453. package/dist/types/signal/api/SignalDigestSyncApi.d.ts +6 -0
  454. package/dist/types/signal/api/SignalIdentitySyncApi.d.ts +2 -0
  455. package/dist/types/signal/api/SignalRotateKeyApi.d.ts +4 -5
  456. package/dist/types/signal/api/SignalSessionSyncApi.d.ts +8 -6
  457. package/dist/types/signal/api/result-map.d.ts +1 -0
  458. package/dist/types/signal/constants.d.ts +0 -3
  459. package/dist/types/signal/{store/sqlite.d.ts → encoding.d.ts} +3 -3
  460. package/dist/types/signal/group/SenderKeyCodec.d.ts +4 -6
  461. package/dist/types/signal/group/SenderKeyManager.d.ts +10 -5
  462. package/dist/types/signal/index.d.ts +3 -0
  463. package/dist/types/signal/session/SignalProtocol.d.ts +19 -4
  464. package/dist/types/signal/session/resolver.d.ts +22 -0
  465. package/dist/types/store/contracts/appstate.store.d.ts +4 -1
  466. package/dist/types/store/contracts/contact.store.d.ts +1 -0
  467. package/dist/types/store/contracts/device-list.store.d.ts +0 -3
  468. package/dist/types/store/contracts/message.store.d.ts +1 -0
  469. package/dist/types/store/contracts/participants.store.d.ts +0 -1
  470. package/dist/types/store/contracts/privacy-token.store.d.ts +16 -0
  471. package/dist/types/store/contracts/retry.store.d.ts +7 -0
  472. package/dist/types/store/contracts/sender-key.store.d.ts +0 -1
  473. package/dist/types/store/contracts/signal.store.d.ts +13 -0
  474. package/dist/types/store/contracts/thread.store.d.ts +1 -0
  475. package/dist/types/store/createStore.d.ts +1 -1
  476. package/dist/types/store/index.d.ts +5 -13
  477. package/dist/types/store/locks/appstate.lock.d.ts +3 -0
  478. package/dist/types/store/locks/auth.lock.d.ts +3 -0
  479. package/dist/types/store/locks/contact.lock.d.ts +3 -0
  480. package/dist/types/store/locks/device-list.lock.d.ts +2 -0
  481. package/dist/types/store/locks/message.lock.d.ts +3 -0
  482. package/dist/types/store/locks/participants.lock.d.ts +2 -0
  483. package/dist/types/store/locks/privacy-token.lock.d.ts +2 -0
  484. package/dist/types/store/locks/retry.lock.d.ts +2 -0
  485. package/dist/types/store/locks/sender-key.lock.d.ts +3 -0
  486. package/dist/types/store/locks/signal.lock.d.ts +3 -0
  487. package/dist/types/store/locks/thread.lock.d.ts +3 -0
  488. package/dist/types/store/providers/memory/appstate.store.d.ts +3 -1
  489. package/dist/types/store/providers/memory/contact.store.d.ts +1 -0
  490. package/dist/types/store/providers/memory/device-list.store.d.ts +0 -3
  491. package/dist/types/store/providers/memory/message.store.d.ts +1 -0
  492. package/dist/types/store/providers/memory/participants.store.d.ts +0 -1
  493. package/dist/types/store/providers/memory/privacy-token.store.d.ts +13 -0
  494. package/dist/types/store/providers/memory/retry.store.d.ts +8 -0
  495. package/dist/types/store/providers/memory/sender-key.store.d.ts +0 -1
  496. package/dist/types/store/providers/memory/signal.store.d.ts +8 -1
  497. package/dist/types/store/providers/memory/thread.store.d.ts +1 -0
  498. package/dist/types/store/types.d.ts +49 -58
  499. package/dist/types/transport/WaWebSocket.d.ts +3 -1
  500. package/dist/types/transport/binary/constants.d.ts +0 -30
  501. package/dist/types/transport/binary/index.d.ts +0 -1
  502. package/dist/types/transport/index.d.ts +2 -1
  503. package/dist/types/transport/keepalive/WaKeepAlive.d.ts +0 -1
  504. package/dist/types/transport/node/WaNodeOrchestrator.d.ts +3 -4
  505. package/dist/types/transport/node/WaNodeTransport.d.ts +0 -9
  506. package/dist/types/transport/node/builders/business.d.ts +29 -0
  507. package/dist/types/transport/node/builders/global.d.ts +102 -0
  508. package/dist/types/transport/node/builders/group.d.ts +4 -6
  509. package/dist/types/transport/node/builders/index.d.ts +7 -3
  510. package/dist/types/transport/node/builders/message.d.ts +20 -30
  511. package/dist/types/transport/node/builders/pairing.d.ts +0 -2
  512. package/dist/types/transport/node/builders/privacy-token.d.ts +9 -0
  513. package/dist/types/transport/node/builders/privacy.d.ts +7 -0
  514. package/dist/types/transport/node/builders/profile.d.ts +8 -0
  515. package/dist/types/transport/node/builders/retry.d.ts +2 -5
  516. package/dist/types/transport/node/builders/usync.d.ts +21 -0
  517. package/dist/types/transport/node/helpers.d.ts +13 -0
  518. package/dist/types/transport/node/usync.d.ts +2 -0
  519. package/dist/types/transport/noise/WaFrameCodec.d.ts +3 -0
  520. package/dist/types/transport/noise/WaNoiseSession.d.ts +4 -2
  521. package/dist/types/transport/noise/WaNoiseSocket.d.ts +4 -2
  522. package/dist/types/transport/proxy.d.ts +6 -0
  523. package/dist/types/transport/stream/parse.d.ts +0 -1
  524. package/dist/types/transport/types.d.ts +18 -1
  525. package/dist/types/util/bytes.d.ts +5 -0
  526. package/dist/types/util/index.d.ts +5 -0
  527. package/dist/types/util/primitives.d.ts +2 -0
  528. package/dist/util/bytes.js +72 -46
  529. package/dist/util/coercion.js +6 -14
  530. package/dist/util/index.js +23 -0
  531. package/dist/util/primitives.js +42 -14
  532. package/package.json +52 -9
  533. package/proto/index.js +1 -1
  534. package/dist/crypto/core/constants.js +0 -4
  535. package/dist/crypto/core/encoding.js +0 -29
  536. package/dist/esm/crypto/core/constants.js +0 -1
  537. package/dist/esm/crypto/core/encoding.js +0 -25
  538. package/dist/esm/retry/outbound.js +0 -83
  539. package/dist/esm/store/providers/sqlite/BaseSqliteStore.js +0 -37
  540. package/dist/esm/store/providers/sqlite/appstate.store.js +0 -169
  541. package/dist/esm/store/providers/sqlite/auth.store.js +0 -176
  542. package/dist/esm/store/providers/sqlite/connection.js +0 -240
  543. package/dist/esm/store/providers/sqlite/contact.store.js +0 -61
  544. package/dist/esm/store/providers/sqlite/device-list.store.js +0 -155
  545. package/dist/esm/store/providers/sqlite/message.store.js +0 -119
  546. package/dist/esm/store/providers/sqlite/migrations.js +0 -347
  547. package/dist/esm/store/providers/sqlite/participants.store.js +0 -85
  548. package/dist/esm/store/providers/sqlite/retry.store.js +0 -144
  549. package/dist/esm/store/providers/sqlite/sender-key.store.js +0 -203
  550. package/dist/esm/store/providers/sqlite/signal.store.js +0 -353
  551. package/dist/esm/store/providers/sqlite/thread.store.js +0 -72
  552. package/dist/esm/util/base64.js +0 -18
  553. package/dist/esm/util/signal-address.js +0 -5
  554. package/dist/retry/outbound.js +0 -88
  555. package/dist/store/providers/sqlite/BaseSqliteStore.js +0 -41
  556. package/dist/store/providers/sqlite/appstate.store.js +0 -173
  557. package/dist/store/providers/sqlite/auth.store.js +0 -180
  558. package/dist/store/providers/sqlite/connection.js +0 -276
  559. package/dist/store/providers/sqlite/contact.store.js +0 -65
  560. package/dist/store/providers/sqlite/device-list.store.js +0 -159
  561. package/dist/store/providers/sqlite/message.store.js +0 -123
  562. package/dist/store/providers/sqlite/migrations.js +0 -350
  563. package/dist/store/providers/sqlite/participants.store.js +0 -89
  564. package/dist/store/providers/sqlite/retry.store.js +0 -148
  565. package/dist/store/providers/sqlite/sender-key.store.js +0 -207
  566. package/dist/store/providers/sqlite/signal.store.js +0 -357
  567. package/dist/store/providers/sqlite/thread.store.js +0 -76
  568. package/dist/types/appstate/store/sqlite.d.ts +0 -21
  569. package/dist/types/crypto/core/constants.d.ts +0 -1
  570. package/dist/types/crypto/core/encoding.d.ts +0 -11
  571. package/dist/types/retry/outbound.d.ts +0 -4
  572. package/dist/types/store/providers/sqlite/BaseSqliteStore.d.ts +0 -12
  573. package/dist/types/store/providers/sqlite/appstate.store.d.ts +0 -15
  574. package/dist/types/store/providers/sqlite/auth.store.d.ts +0 -10
  575. package/dist/types/store/providers/sqlite/connection.d.ts +0 -10
  576. package/dist/types/store/providers/sqlite/contact.store.d.ts +0 -10
  577. package/dist/types/store/providers/sqlite/device-list.store.d.ts +0 -18
  578. package/dist/types/store/providers/sqlite/message.store.d.ts +0 -11
  579. package/dist/types/store/providers/sqlite/migrations.d.ts +0 -3
  580. package/dist/types/store/providers/sqlite/participants.store.d.ts +0 -13
  581. package/dist/types/store/providers/sqlite/retry.store.d.ts +0 -16
  582. package/dist/types/store/providers/sqlite/sender-key.store.d.ts +0 -25
  583. package/dist/types/store/providers/sqlite/signal.store.d.ts +0 -46
  584. package/dist/types/store/providers/sqlite/thread.store.d.ts +0 -11
  585. package/dist/types/util/base64.d.ts +0 -4
  586. package/dist/types/util/signal-address.d.ts +0 -2
  587. package/dist/util/base64.js +0 -24
  588. package/dist/util/signal-address.js +0 -8
  589. /package/dist/types/transport/node/builders/{accountSync.d.ts → account-sync.d.ts} +0 -0
@@ -1,17 +1,33 @@
1
1
  import { WaAppStateSyncClient } from '../appstate/WaAppStateSyncClient.js';
2
2
  import { WaAuthClient } from '../auth/WaAuthClient.js';
3
+ import { WaConnectionManager } from './connection/WaConnectionManager.js';
4
+ import { WaKeyShareCoordinator } from './connection/WaKeyShareCoordinator.js';
5
+ import { WaReceiptQueue } from './connection/WaReceiptQueue.js';
6
+ import { WaAppStateMutationCoordinator } from './coordinators/WaAppStateMutationCoordinator.js';
7
+ import { createBusinessCoordinator } from './coordinators/WaBusinessCoordinator.js';
3
8
  import { createGroupCoordinator } from './coordinators/WaGroupCoordinator.js';
4
9
  import { WaIncomingNodeCoordinator } from './coordinators/WaIncomingNodeCoordinator.js';
5
10
  import { WaMessageDispatchCoordinator } from './coordinators/WaMessageDispatchCoordinator.js';
6
11
  import { WaPassiveTasksCoordinator } from './coordinators/WaPassiveTasksCoordinator.js';
12
+ import { createPrivacyCoordinator } from './coordinators/WaPrivacyCoordinator.js';
13
+ import { createProfileCoordinator } from './coordinators/WaProfileCoordinator.js';
7
14
  import { WaRetryCoordinator } from './coordinators/WaRetryCoordinator.js';
8
15
  import { createStreamControlHandler } from './coordinators/WaStreamControlCoordinator.js';
16
+ import { WaTrustedContactTokenCoordinator } from './coordinators/WaTrustedContactTokenCoordinator.js';
9
17
  import { handleDirtyBits, parseDirtyBits } from './dirty.js';
18
+ import { DEVICE_NOTIFICATION_ACTIONS, parseDeviceNotification } from './events/devices.js';
19
+ import { parseIdentityChangeNotification } from './events/identity.js';
20
+ import { parsePrivacyTokenNotification } from './events/privacy-token.js';
10
21
  import { buildMediaMessageContent, getMediaConn as getClientMediaConn } from './messages.js';
22
+ import { createDeviceFanoutResolver } from './messaging/fanout.js';
23
+ import { createAppStateSyncKeyProtocol } from './messaging/key-protocol.js';
24
+ import { createGroupParticipantsCache } from './messaging/participants.js';
11
25
  import { WaMediaTransferClient } from '../media/WaMediaTransferClient.js';
12
26
  import { handleIncomingMessageAck } from '../message/incoming.js';
13
27
  import { WaMessageClient } from '../message/WaMessageClient.js';
14
- import { getWaCompanionPlatformId, WA_DEFAULTS } from '../protocol/constants.js';
28
+ import { getWaCompanionPlatformId, WA_DEFAULTS, WA_DISCONNECT_REASONS, WA_NODE_TAGS, WA_NOTIFICATION_TYPES, WA_PRIVACY_TOKEN_NOTIFICATION_TYPE } from '../protocol/constants.js';
29
+ import { parseSignalAddressFromJid, toUserJid } from '../protocol/jid.js';
30
+ import { createOutboundRetryTracker } from '../retry/tracker.js';
15
31
  import { SignalDeviceSyncApi } from '../signal/api/SignalDeviceSyncApi.js';
16
32
  import { SignalDigestSyncApi } from '../signal/api/SignalDigestSyncApi.js';
17
33
  import { SignalIdentitySyncApi } from '../signal/api/SignalIdentitySyncApi.js';
@@ -19,13 +35,40 @@ import { SignalMissingPreKeysSyncApi } from '../signal/api/SignalMissingPreKeysS
19
35
  import { SignalRotateKeyApi } from '../signal/api/SignalRotateKeyApi.js';
20
36
  import { SignalSessionSyncApi } from '../signal/api/SignalSessionSyncApi.js';
21
37
  import { SenderKeyManager } from '../signal/group/SenderKeyManager.js';
38
+ import { createSignalSessionResolver } from '../signal/session/resolver.js';
22
39
  import { SignalProtocol } from '../signal/session/SignalProtocol.js';
23
40
  import { WaKeepAlive } from '../transport/keepalive/WaKeepAlive.js';
41
+ import { buildAckNode } from '../transport/node/builders/global.js';
42
+ import { getFirstNodeChild } from '../transport/node/helpers.js';
43
+ import { createUsyncSidGenerator } from '../transport/node/usync.js';
24
44
  import { WaNodeOrchestrator } from '../transport/node/WaNodeOrchestrator.js';
25
45
  import { WaNodeTransport } from '../transport/node/WaNodeTransport.js';
46
+ import { isProxyTransport, toProxyAgent, toProxyDispatcher } from '../transport/proxy.js';
26
47
  import { toError } from '../util/primitives.js';
27
48
  import { getRuntimeOsDisplayName } from '../util/runtime.js';
49
+ function assertProxyTransport(value, path) {
50
+ if (value === undefined) {
51
+ return;
52
+ }
53
+ if (!isProxyTransport(value)) {
54
+ throw new Error(`${path} must be a proxy transport instance (dispatcher with dispatch(...) or agent with addRequest(...))`);
55
+ }
56
+ }
57
+ function validateProxyOptions(options) {
58
+ const rawProxy = options.proxy;
59
+ if (rawProxy === undefined) {
60
+ return;
61
+ }
62
+ if (typeof rawProxy !== 'object' || rawProxy === null || Array.isArray(rawProxy)) {
63
+ throw new Error('proxy must be an object with optional ws/mediaUpload/mediaDownload');
64
+ }
65
+ const proxy = rawProxy;
66
+ assertProxyTransport(proxy?.ws, 'proxy.ws');
67
+ assertProxyTransport(proxy?.mediaUpload, 'proxy.mediaUpload');
68
+ assertProxyTransport(proxy?.mediaDownload, 'proxy.mediaDownload');
69
+ }
28
70
  export function resolveWaClientBase(options, logger) {
71
+ validateProxyOptions(options);
29
72
  const deviceBrowser = options.deviceBrowser ?? WA_DEFAULTS.DEVICE_BROWSER;
30
73
  const sessionId = options.sessionId.trim();
31
74
  if (sessionId.length === 0) {
@@ -57,79 +100,14 @@ export function resolveWaClientBase(options, logger) {
57
100
  sessionStore
58
101
  };
59
102
  }
60
- function createAuthClient(input) {
61
- const { options, logger, sessionStore, host } = input;
62
- return new WaAuthClient({
63
- deviceBrowser: options.deviceBrowser,
64
- deviceOsDisplayName: options.deviceOsDisplayName,
65
- devicePlatform: options.devicePlatform,
66
- requireFullSync: options.requireFullSync
67
- }, {
68
- logger,
69
- authStore: sessionStore.auth,
70
- signalStore: sessionStore.signal,
71
- socket: {
72
- sendNode: host.sendNode,
73
- query: host.query
74
- },
75
- callbacks: {
76
- onQr: (qr, ttlMs) => host.emitEvent('auth_qr', { qr, ttlMs }),
77
- onPairingCode: (code) => host.emitEvent('auth_pairing_code', { code }),
78
- onPairingRefresh: (forceManual) => host.emitEvent('auth_pairing_refresh', { forceManual }),
79
- onPaired: (credentials) => {
80
- host.emitEvent('auth_paired', { credentials });
81
- host.scheduleReconnectAfterPairing();
82
- },
83
- onError: (error) => host.handleError(error)
84
- }
85
- });
86
- }
87
- function createCurrentAuthGetters(authClient) {
88
- const getCurrentCredentials = () => authClient.getCurrentCredentials();
89
- return {
90
- getCurrentCredentials,
91
- getCurrentMeJid: () => getCurrentCredentials()?.meJid,
92
- getCurrentMeLid: () => getCurrentCredentials()?.meLid,
93
- getCurrentSignedIdentity: () => getCurrentCredentials()?.signedIdentity
94
- };
95
- }
96
- function createIncomingMessageAckOptions(input) {
97
- const { logger, host, getCurrentMeJid, signalProtocol, senderKeyManager, retryCoordinator } = input;
98
- return {
99
- logger,
100
- sendNode: host.sendNode,
101
- getMeJid: getCurrentMeJid,
102
- signalProtocol,
103
- senderKeyManager,
104
- onDecryptFailure: (context, error) => retryCoordinator.onDecryptFailure(context, error),
105
- emitIncomingMessage: (event) => {
106
- void host
107
- .handleIncomingMessageEvent(event)
108
- .catch((err) => host.handleError(toError(err)));
109
- },
110
- emitUnhandledStanza: (event) => host.emitEvent('stanza_unhandled', event)
111
- };
112
- }
113
- function createHandleClientDirtyBits(input) {
114
- const { logger, host, getCurrentCredentials } = input;
115
- return (dirtyBits) => handleDirtyBits({
116
- logger,
117
- queryWithContext: host.queryWithContext,
118
- getCurrentCredentials,
119
- syncAppState: host.syncAppState
120
- }, dirtyBits);
121
- }
122
103
  function createIncomingNodeRuntime(input) {
123
- const { logger, host, authClient, nodeOrchestrator, streamControl, mediaMessageBuildOptions, retryCoordinator, messageDispatch, getCurrentMeJid, handleClientDirtyBits, incomingMessageAckOptions } = input;
104
+ const { logger, emitEvent, authClient, connectionManager, nodeOrchestrator, streamControl, mediaMessageBuildOptions, retryCoordinator, messageDispatch, sendNode, syncAppState, disconnect, clearStoredCredentials, getCurrentMeJid, handleClientDirtyBits, incomingMessageAckOptions } = input;
124
105
  return {
125
106
  handleStreamControlResult: streamControl.handleStreamControlResult,
126
107
  persistSuccessAttributes: (attributes) => authClient.persistSuccessAttributes(attributes),
127
- emitSuccessNode: (node) => host.emitEvent('connection_success', { node }),
128
- updateClockSkewFromSuccess: host.updateClockSkewFromSuccess,
129
- shouldWarmupMediaConn: () => {
130
- const comms = host.getComms();
131
- return !!(getCurrentMeJid() && comms && comms.getCommsState().connected);
132
- },
108
+ emitSuccessNode: (node) => emitEvent('connection_success', { node }),
109
+ updateClockSkewFromSuccess: (serverUnixSeconds) => connectionManager.updateClockSkewFromSuccess(serverUnixSeconds),
110
+ shouldWarmupMediaConn: () => !!(getCurrentMeJid() && connectionManager.isConnected()),
133
111
  warmupMediaConn: async () => {
134
112
  await getClientMediaConn(mediaMessageBuildOptions, true);
135
113
  },
@@ -140,18 +118,18 @@ function createIncomingNodeRuntime(input) {
140
118
  handleLinkCodeNotificationNode: (node) => authClient.handleLinkCodeNotification(node),
141
119
  handleCompanionRegRefreshNotificationNode: (node) => authClient.handleCompanionRegRefreshNotification(node),
142
120
  handleIncomingMessageNode: (node) => handleIncomingMessageAck(node, incomingMessageAckOptions),
143
- sendNode: host.sendNode,
121
+ sendNode,
144
122
  handleIncomingRetryReceipt: (node) => retryCoordinator.handleIncomingRetryReceipt(node),
145
123
  trackOutboundReceipt: (node) => retryCoordinator.trackOutboundReceipt(node),
146
- emitIncomingReceipt: (event) => host.emitEvent('message_receipt', event),
147
- emitIncomingPresence: (event) => host.emitEvent('presence', event),
148
- emitIncomingChatstate: (event) => host.emitEvent('chatstate', event),
149
- emitIncomingCall: (event) => host.emitEvent('call', event),
150
- emitIncomingFailure: (event) => host.emitEvent('failure', event),
151
- emitIncomingErrorStanza: (event) => host.emitEvent('stanza_error', event),
152
- emitIncomingNotification: (event) => host.emitEvent('notification', event),
124
+ emitIncomingReceipt: (event) => emitEvent('message_receipt', event),
125
+ emitIncomingPresence: (event) => emitEvent('presence', event),
126
+ emitIncomingChatstate: (event) => emitEvent('chatstate', event),
127
+ emitIncomingCall: (event) => emitEvent('call', event),
128
+ emitIncomingFailure: (event) => emitEvent('failure', event),
129
+ emitIncomingErrorStanza: (event) => emitEvent('stanza_error', event),
130
+ emitIncomingNotification: (event) => emitEvent('notification', event),
153
131
  emitGroupEvent: (event) => {
154
- host.emitEvent('group_event', event);
132
+ emitEvent('group_event', event);
155
133
  void messageDispatch.mutateParticipantsCacheFromGroupEvent(event).catch((error) => {
156
134
  logger.warn('failed to mutate participants cache from group event', {
157
135
  action: event.action,
@@ -161,29 +139,38 @@ function createIncomingNodeRuntime(input) {
161
139
  });
162
140
  });
163
141
  },
164
- emitUnhandledIncomingNode: (event) => host.emitEvent('stanza_unhandled', event),
165
- syncAppState: host.syncAppState,
166
- disconnect: host.disconnect,
167
- clearStoredCredentials: host.clearStoredState,
142
+ emitUnhandledIncomingNode: (event) => emitEvent('stanza_unhandled', event),
143
+ syncAppState,
144
+ stopComms: () => {
145
+ void connectionManager.getComms()?.stopComms();
146
+ },
147
+ disconnect,
148
+ clearStoredCredentials,
168
149
  parseDirtyBits: (nodes) => parseDirtyBits(nodes, logger),
169
150
  handleDirtyBits: (dirtyBits) => handleClientDirtyBits(dirtyBits)
170
151
  };
171
152
  }
172
153
  function createPassiveTasksRuntime(input) {
173
- const { host, authClient, nodeOrchestrator, getCurrentCredentials } = input;
154
+ const { queryWithContext, authClient, nodeOrchestrator, receiptQueue, getCurrentCredentials } = input;
174
155
  return {
175
- queryWithContext: host.queryWithContext,
156
+ queryWithContext,
176
157
  getCurrentCredentials,
177
158
  persistServerHasPreKeys: (serverHasPreKeys) => authClient.persistServerHasPreKeys(serverHasPreKeys),
178
159
  sendNodeDirect: (node) => nodeOrchestrator.sendNode(node),
179
- takeDanglingReceipts: host.takeDanglingReceipts,
180
- requeueDanglingReceipt: host.enqueueDanglingReceipt,
181
- shouldQueueDanglingReceipt: host.shouldQueueDanglingReceipt
160
+ takeDanglingReceipts: () => receiptQueue.take(),
161
+ requeueDanglingReceipt: (node) => receiptQueue.enqueue(node),
162
+ shouldQueueDanglingReceipt: (node, error) => receiptQueue.shouldQueue(node, error)
182
163
  };
183
164
  }
184
165
  export function buildWaClientDependencies(input) {
185
- const { base, host } = input;
166
+ const { base, runtime } = input;
186
167
  const { options, logger, sessionStore } = base;
168
+ const receiptQueue = new WaReceiptQueue();
169
+ const keyShareCoordinator = new WaKeyShareCoordinator();
170
+ let connectionManager = null;
171
+ let passiveTasks = null;
172
+ let mediaConnCacheFallback = null;
173
+ let scheduleReconnectAfterPairing = () => undefined;
187
174
  const nodeTransport = new WaNodeTransport(logger);
188
175
  const nodeOrchestrator = new WaNodeOrchestrator({
189
176
  sendNode: async (node) => nodeTransport.sendNode(node),
@@ -194,27 +181,39 @@ export function buildWaClientDependencies(input) {
194
181
  const keepAlive = new WaKeepAlive({
195
182
  logger,
196
183
  nodeOrchestrator,
197
- getComms: host.getComms,
184
+ getComms: () => connectionManager?.getComms() ?? null,
198
185
  intervalMs: options.keepAliveIntervalMs,
199
186
  timeoutMs: options.deadSocketTimeoutMs,
200
187
  hostDomain: WA_DEFAULTS.HOST_DOMAIN
201
188
  });
202
189
  const mediaTransfer = new WaMediaTransferClient({
203
190
  logger,
204
- defaultTimeoutMs: options.mediaTimeoutMs
191
+ defaultTimeoutMs: options.mediaTimeoutMs,
192
+ defaultUploadDispatcher: toProxyDispatcher(options.proxy?.mediaUpload),
193
+ defaultDownloadDispatcher: toProxyDispatcher(options.proxy?.mediaDownload),
194
+ defaultUploadAgent: toProxyAgent(options.proxy?.mediaUpload),
195
+ defaultDownloadAgent: toProxyAgent(options.proxy?.mediaDownload)
205
196
  });
206
197
  const mediaMessageBuildOptions = {
207
198
  logger,
208
199
  mediaTransfer,
209
200
  iqTimeoutMs: options.iqTimeoutMs,
210
- queryWithContext: host.queryWithContext,
211
- getMediaConnCache: host.getMediaConnCache,
212
- setMediaConnCache: host.setMediaConnCache
201
+ queryWithContext: runtime.queryWithContext,
202
+ getMediaConnCache: () => {
203
+ if (connectionManager) {
204
+ return connectionManager.getMediaConnCache();
205
+ }
206
+ return mediaConnCacheFallback;
207
+ },
208
+ setMediaConnCache: (mediaConn) => {
209
+ mediaConnCacheFallback = mediaConn;
210
+ connectionManager?.setMediaConnCache(mediaConn);
211
+ }
213
212
  };
214
213
  const messageClient = new WaMessageClient({
215
214
  logger,
216
- sendNode: host.sendNode,
217
- query: host.query,
215
+ sendNode: runtime.sendNode,
216
+ query: runtime.query,
218
217
  defaultAckTimeoutMs: options.messageAckTimeoutMs,
219
218
  defaultMaxAttempts: options.messageMaxAttempts,
220
219
  defaultRetryDelayMs: options.messageRetryDelayMs
@@ -223,59 +222,156 @@ export function buildWaClientDependencies(input) {
223
222
  const signalProtocol = new SignalProtocol(sessionStore.signal, logger);
224
223
  const signalDigestSync = new SignalDigestSyncApi({
225
224
  logger,
226
- query: host.query,
225
+ query: runtime.query,
227
226
  signalStore: sessionStore.signal,
228
227
  defaultTimeoutMs: options.signalFetchKeyBundlesTimeoutMs
229
228
  });
229
+ const generateUsyncSid = createUsyncSidGenerator();
230
230
  const signalDeviceSync = new SignalDeviceSyncApi({
231
231
  logger,
232
- query: host.query,
232
+ query: runtime.query,
233
233
  deviceListStore: sessionStore.deviceList,
234
- defaultTimeoutMs: options.signalFetchKeyBundlesTimeoutMs
234
+ defaultTimeoutMs: options.signalFetchKeyBundlesTimeoutMs,
235
+ generateSid: generateUsyncSid
235
236
  });
236
237
  const signalIdentitySync = new SignalIdentitySyncApi({
237
238
  logger,
238
- query: host.query,
239
+ query: runtime.query,
239
240
  signalStore: sessionStore.signal,
240
241
  defaultTimeoutMs: options.signalFetchKeyBundlesTimeoutMs
241
242
  });
242
243
  const signalMissingPreKeysSync = new SignalMissingPreKeysSyncApi({
243
244
  logger,
244
- query: host.query,
245
+ query: runtime.query,
245
246
  defaultTimeoutMs: options.signalFetchKeyBundlesTimeoutMs
246
247
  });
247
248
  const signalRotateKey = new SignalRotateKeyApi({
248
249
  logger,
249
- query: host.query,
250
+ query: runtime.query,
250
251
  signalStore: sessionStore.signal,
251
252
  defaultTimeoutMs: options.signalFetchKeyBundlesTimeoutMs
252
253
  });
253
254
  const signalSessionSync = new SignalSessionSyncApi({
254
255
  logger,
255
- query: host.query,
256
+ query: runtime.query,
256
257
  defaultTimeoutMs: options.signalFetchKeyBundlesTimeoutMs
257
258
  });
258
- const authClient = createAuthClient({ options, logger, sessionStore, host });
259
- const { getCurrentCredentials, getCurrentMeJid, getCurrentMeLid, getCurrentSignedIdentity } = createCurrentAuthGetters(authClient);
259
+ const authClient = new WaAuthClient({
260
+ deviceBrowser: options.deviceBrowser,
261
+ deviceOsDisplayName: options.deviceOsDisplayName,
262
+ devicePlatform: options.devicePlatform,
263
+ requireFullSync: options.requireFullSync,
264
+ version: options.version
265
+ }, {
266
+ logger,
267
+ authStore: sessionStore.auth,
268
+ signalStore: sessionStore.signal,
269
+ socket: {
270
+ sendNode: runtime.sendNode,
271
+ query: runtime.query
272
+ },
273
+ callbacks: {
274
+ onQr: (qr, ttlMs) => runtime.emitEvent('auth_qr', { qr, ttlMs }),
275
+ onPairingCode: (code) => runtime.emitEvent('auth_pairing_code', { code }),
276
+ onPairingRefresh: (forceManual) => runtime.emitEvent('auth_pairing_refresh', { forceManual }),
277
+ onPaired: (credentials) => {
278
+ runtime.emitEvent('auth_paired', { credentials });
279
+ scheduleReconnectAfterPairing();
280
+ },
281
+ onError: (error) => runtime.handleError(error)
282
+ }
283
+ });
284
+ const getCurrentCredentials = authClient.getCurrentCredentials.bind(authClient);
285
+ const getCurrentMeJid = () => getCurrentCredentials()?.meJid;
286
+ const getCurrentMeLid = () => getCurrentCredentials()?.meLid;
287
+ const getCurrentSignedIdentity = () => getCurrentCredentials()?.signedIdentity;
260
288
  const groupCoordinator = createGroupCoordinator({
261
- queryWithContext: host.queryWithContext
289
+ queryWithContext: runtime.queryWithContext
262
290
  });
263
- const messageDispatch = new WaMessageDispatchCoordinator({
264
- logger,
265
- messageClient,
291
+ const privacyCoordinator = createPrivacyCoordinator({
292
+ queryWithContext: runtime.queryWithContext
293
+ });
294
+ const profileCoordinator = createProfileCoordinator({
295
+ queryWithContext: runtime.queryWithContext,
296
+ generateSid: generateUsyncSid
297
+ });
298
+ const businessCoordinator = createBusinessCoordinator({
299
+ queryWithContext: runtime.queryWithContext
300
+ });
301
+ const retryTracker = createOutboundRetryTracker({
266
302
  retryStore: sessionStore.retry,
303
+ logger
304
+ });
305
+ const sessionResolver = createSignalSessionResolver({
306
+ signalProtocol,
307
+ signalStore: sessionStore.signal,
308
+ signalIdentitySync,
309
+ signalSessionSync,
310
+ logger
311
+ });
312
+ const fanoutResolver = createDeviceFanoutResolver({
313
+ signalDeviceSync,
314
+ getCurrentMeJid,
315
+ getCurrentMeLid,
316
+ logger
317
+ });
318
+ const participantsCache = createGroupParticipantsCache({
267
319
  participantsStore: sessionStore.participants,
320
+ queryGroupParticipantJids: async (groupJid) => {
321
+ const metadata = await groupCoordinator.queryGroupMetadata(groupJid);
322
+ const participantJids = new Array(metadata.participants.length);
323
+ for (let index = 0; index < metadata.participants.length; index += 1) {
324
+ participantJids[index] = metadata.participants[index].jid;
325
+ }
326
+ return participantJids;
327
+ },
328
+ logger
329
+ });
330
+ const trustedContactToken = new WaTrustedContactTokenCoordinator({
331
+ logger,
332
+ store: sessionStore.privacyToken,
333
+ runtime: {
334
+ queryWithContext: runtime.queryWithContext,
335
+ emitEvent: runtime.emitEvent,
336
+ getCurrentMeLid: () => getCurrentMeLid() ?? null
337
+ },
338
+ durationS: options.privacyToken?.tcTokenDurationS,
339
+ numBuckets: options.privacyToken?.tcTokenNumBuckets,
340
+ senderDurationS: options.privacyToken?.tcTokenSenderDurationS,
341
+ senderNumBuckets: options.privacyToken?.tcTokenSenderNumBuckets,
342
+ maxDurationS: options.privacyToken?.tcTokenMaxDurationS
343
+ });
344
+ let messageDispatch;
345
+ const appStateSyncKeyProtocol = createAppStateSyncKeyProtocol({
346
+ publishSignalMessage: (signalInput, publishOptions) => messageDispatch.publishSignalMessage(signalInput, publishOptions),
347
+ fanoutResolver,
348
+ getCurrentMeJid,
349
+ getCurrentMeLid,
350
+ logger
351
+ });
352
+ messageDispatch = new WaMessageDispatchCoordinator({
353
+ logger,
354
+ messageClient,
355
+ retryTracker,
356
+ sessionResolver,
357
+ fanoutResolver,
358
+ participantsCache,
359
+ appStateSyncKeyProtocol,
268
360
  buildMessageContent: async (content) => buildMediaMessageContent(mediaMessageBuildOptions, content),
269
- queryGroupParticipantJids: async (groupJid) => (await groupCoordinator.queryGroupMetadata(groupJid)).participants.map((participant) => participant.jid),
270
361
  senderKeyManager,
271
362
  signalProtocol,
272
363
  signalStore: sessionStore.signal,
273
- signalDeviceSync,
274
- signalIdentitySync,
275
- signalSessionSync,
364
+ deviceListStore: sessionStore.deviceList,
276
365
  getCurrentMeJid,
277
366
  getCurrentMeLid,
278
- getCurrentSignedIdentity
367
+ getCurrentSignedIdentity,
368
+ resolvePrivacyTokenNode: (recipientJid) => trustedContactToken.resolveTokenForMessage(recipientJid),
369
+ onDirectMessageSent: (recipientJid) => {
370
+ trustedContactToken.maybeIssueSenderToken(recipientJid).catch((err) => logger.warn('sender token issue failed', {
371
+ to: recipientJid,
372
+ message: toError(err).message
373
+ }));
374
+ }
279
375
  });
280
376
  const retryCoordinator = new WaRetryCoordinator({
281
377
  logger,
@@ -286,67 +382,330 @@ export function buildWaClientDependencies(input) {
286
382
  signalDeviceSync,
287
383
  signalMissingPreKeysSync,
288
384
  messageClient,
289
- sendNode: host.sendNode,
385
+ sendNode: runtime.sendNode,
290
386
  getCurrentMeJid,
291
387
  getCurrentMeLid,
292
388
  getCurrentSignedIdentity
293
389
  });
294
390
  const appStateSync = new WaAppStateSyncClient({
295
391
  logger,
296
- query: host.query,
392
+ query: runtime.query,
393
+ getCurrentMeJid,
297
394
  defaultTimeoutMs: options.appStateSyncTimeoutMs,
298
395
  store: sessionStore.appState,
299
396
  onMissingKeys: async ({ keyIds }) => {
300
397
  await messageDispatch.requestAppStateSyncKeys(keyIds);
301
398
  }
302
399
  });
400
+ const appStateMutations = new WaAppStateMutationCoordinator({
401
+ logger,
402
+ messageStore: sessionStore.messages,
403
+ syncAppState: runtime.syncAppStateWithOptions
404
+ });
405
+ connectionManager = new WaConnectionManager({
406
+ logger,
407
+ options,
408
+ authClient,
409
+ keepAlive,
410
+ nodeOrchestrator,
411
+ nodeTransport,
412
+ getPassiveTasks: () => passiveTasks,
413
+ clearStoredCredentials: runtime.clearStoredState
414
+ });
415
+ if (mediaConnCacheFallback !== null) {
416
+ connectionManager.setMediaConnCache(mediaConnCacheFallback);
417
+ }
418
+ scheduleReconnectAfterPairing = () => connectionManager?.scheduleReconnectAfterPairing();
419
+ const disconnectWithClientSideEffects = async (reason, isLogout, code) => {
420
+ keyShareCoordinator.notifyDisconnected();
421
+ await connectionManager?.disconnect();
422
+ runtime.emitEvent('connection', {
423
+ status: 'close',
424
+ reason,
425
+ code,
426
+ isLogout,
427
+ isNewLogin: false
428
+ });
429
+ };
430
+ const connectWithClientSideEffects = async (reason) => {
431
+ runtime.resumeIncomingEvents();
432
+ await connectionManager?.connect(runtime.handleIncomingFrame);
433
+ runtime.emitEvent('connection', {
434
+ status: 'open',
435
+ reason,
436
+ code: null,
437
+ isLogout: false,
438
+ isNewLogin: connectionManager?.wasNewLogin() ?? false
439
+ });
440
+ };
441
+ const clearStoredCredentialsWithClientSideEffects = async () => {
442
+ await connectionManager?.clearStoredCredentials();
443
+ };
303
444
  const streamControl = createStreamControlHandler({
304
445
  logger,
305
- getComms: host.getComms,
446
+ getComms: () => connectionManager?.getComms() ?? null,
306
447
  clearPendingQueries: (error) => nodeOrchestrator.clearPending(error),
307
- clearMediaConnCache: () => host.setMediaConnCache(null),
308
- disconnect: host.disconnect,
309
- clearStoredCredentials: host.clearStoredState,
310
- connect: host.connect
448
+ clearMediaConnCache: () => {
449
+ mediaConnCacheFallback = null;
450
+ connectionManager?.setMediaConnCache(null);
451
+ },
452
+ disconnect: disconnectWithClientSideEffects,
453
+ clearStoredCredentials: clearStoredCredentialsWithClientSideEffects,
454
+ connect: connectWithClientSideEffects
311
455
  });
312
- const incomingMessageAckOptions = createIncomingMessageAckOptions({
456
+ const incomingMessageAckOptions = {
313
457
  logger,
314
- host,
315
- getCurrentMeJid,
458
+ sendNode: runtime.sendNode,
459
+ getMeJid: getCurrentMeJid,
316
460
  signalProtocol,
317
461
  senderKeyManager,
318
- retryCoordinator
319
- });
320
- const handleClientDirtyBits = createHandleClientDirtyBits({
462
+ onDecryptFailure: (context, error) => retryCoordinator.onDecryptFailure(context, error),
463
+ emitIncomingMessage: (event) => {
464
+ void runtime
465
+ .handleIncomingMessageEvent(event)
466
+ .catch((err) => runtime.handleError(toError(err)));
467
+ },
468
+ emitUnhandledStanza: (event) => runtime.emitEvent('stanza_unhandled', event)
469
+ };
470
+ const handleClientDirtyBits = (dirtyBits) => handleDirtyBits({
321
471
  logger,
322
- host,
323
- getCurrentCredentials
324
- });
472
+ queryWithContext: runtime.queryWithContext,
473
+ getCurrentCredentials,
474
+ syncAppState: runtime.syncAppState,
475
+ generateUsyncSid
476
+ }, dirtyBits);
325
477
  const incomingNode = new WaIncomingNodeCoordinator({
326
478
  logger,
327
479
  runtime: createIncomingNodeRuntime({
328
480
  logger,
329
- host,
481
+ emitEvent: runtime.emitEvent,
330
482
  authClient,
483
+ connectionManager,
331
484
  nodeOrchestrator,
332
485
  streamControl,
333
486
  mediaMessageBuildOptions,
334
487
  retryCoordinator,
335
488
  messageDispatch,
489
+ sendNode: runtime.sendNode,
490
+ syncAppState: runtime.syncAppState,
491
+ disconnect: disconnectWithClientSideEffects,
492
+ clearStoredCredentials: clearStoredCredentialsWithClientSideEffects,
336
493
  getCurrentMeJid,
337
494
  handleClientDirtyBits,
338
495
  incomingMessageAckOptions
339
496
  })
340
497
  });
341
- const passiveTasks = new WaPassiveTasksCoordinator({
498
+ incomingNode.registerIncomingHandler({
499
+ tag: WA_NODE_TAGS.NOTIFICATION,
500
+ subtype: WA_NOTIFICATION_TYPES.ENCRYPT,
501
+ prepend: true,
502
+ handler: async (node) => {
503
+ const firstChild = getFirstNodeChild(node);
504
+ if (!firstChild) {
505
+ return false;
506
+ }
507
+ const childTag = firstChild.tag;
508
+ // <count value="N"/> — server prekeys running low
509
+ if (childTag === 'count') {
510
+ const ackNode = buildAckNode({
511
+ kind: 'notification',
512
+ node,
513
+ includeType: false
514
+ });
515
+ await runtime.sendNode(ackNode);
516
+ const tasks = passiveTasks;
517
+ if (!tasks) {
518
+ logger.warn('encrypt-count: passive tasks not available');
519
+ return true;
520
+ }
521
+ await tasks.handlePreKeyLowNotification().catch((error) => {
522
+ logger.warn('encrypt-count: prekey upload failed', {
523
+ message: toError(error).message
524
+ });
525
+ });
526
+ return true;
527
+ }
528
+ // <digest/> — digest key sync
529
+ if (childTag === 'digest') {
530
+ const ackNode = buildAckNode({
531
+ kind: 'notification',
532
+ node,
533
+ includeType: false
534
+ });
535
+ await runtime.sendNode(ackNode);
536
+ const tasks = passiveTasks;
537
+ if (!tasks) {
538
+ logger.warn('encrypt-digest: passive tasks not available');
539
+ return true;
540
+ }
541
+ await tasks.handleDigestNotification().catch((error) => {
542
+ logger.warn('encrypt-digest: digest sync failed', {
543
+ message: toError(error).message
544
+ });
545
+ });
546
+ return true;
547
+ }
548
+ // <identity/> — contact identity key changed
549
+ if (childTag === 'identity') {
550
+ const parsed = parseIdentityChangeNotification(node);
551
+ if (!parsed) {
552
+ return false;
553
+ }
554
+ const ackNode = buildAckNode({
555
+ kind: 'notification',
556
+ node,
557
+ includeType: false
558
+ });
559
+ await runtime.sendNode(ackNode);
560
+ const address = parseSignalAddressFromJid(parsed.fromJid);
561
+ // ignore companion devices (non-primary)
562
+ if (address.device !== 0) {
563
+ logger.debug('identity-change: ignoring companion device', {
564
+ jid: parsed.fromJid
565
+ });
566
+ return true;
567
+ }
568
+ // self-primary identity change → must disconnect
569
+ const meJid = getCurrentMeJid();
570
+ if (meJid) {
571
+ const meUser = toUserJid(meJid);
572
+ const fromUser = toUserJid(parsed.fromJid);
573
+ if (meUser === fromUser) {
574
+ logger.error('self primary identity changed, disconnecting');
575
+ void connectionManager?.getComms()?.stopComms();
576
+ await disconnectWithClientSideEffects(WA_DISCONNECT_REASONS.PRIMARY_IDENTITY_KEY_CHANGE, true, null);
577
+ await clearStoredCredentialsWithClientSideEffects();
578
+ return true;
579
+ }
580
+ }
581
+ const oldIdentity = await sessionStore.signal.getRemoteIdentity(address);
582
+ if (oldIdentity) {
583
+ logger.info('identity-change: clearing session', {
584
+ jid: parsed.fromJid
585
+ });
586
+ await sessionStore.signal.deleteSession(address);
587
+ const userJid = toUserJid(parsed.fromJid);
588
+ await trustedContactToken.reissueOnIdentityChange(userJid).catch((error) => {
589
+ logger.warn('identity-change: reissue tc token failed', {
590
+ message: toError(error).message
591
+ });
592
+ });
593
+ }
594
+ runtime.emitEvent('notification', {
595
+ rawNode: node,
596
+ stanzaId: parsed.stanzaId,
597
+ chatJid: parsed.fromJid,
598
+ stanzaType: 'encrypt',
599
+ notificationType: 'encrypt',
600
+ classification: 'core',
601
+ details: {
602
+ kind: 'identity_change',
603
+ displayName: parsed.displayName,
604
+ lid: parsed.lid,
605
+ hadPreviousIdentity: !!oldIdentity
606
+ }
607
+ });
608
+ return true;
609
+ }
610
+ return false;
611
+ }
612
+ });
613
+ incomingNode.registerIncomingHandler({
614
+ tag: WA_NODE_TAGS.NOTIFICATION,
615
+ subtype: WA_NOTIFICATION_TYPES.DEVICES,
616
+ prepend: true,
617
+ handler: async (node) => {
618
+ const parsed = parseDeviceNotification(node);
619
+ if (!parsed) {
620
+ return false;
621
+ }
622
+ const ackNode = buildAckNode({
623
+ kind: 'notification',
624
+ node,
625
+ includeType: false
626
+ });
627
+ await runtime.sendNode(ackNode);
628
+ const userJid = toUserJid(parsed.fromJid);
629
+ if (parsed.action === DEVICE_NOTIFICATION_ACTIONS.REMOVE) {
630
+ const baseAddress = parseSignalAddressFromJid(parsed.fromJid);
631
+ for (const device of parsed.devices) {
632
+ const address = {
633
+ user: baseAddress.user,
634
+ server: baseAddress.server,
635
+ device: device.deviceId
636
+ };
637
+ await sessionStore.signal.deleteSession(address).catch((error) => {
638
+ logger.warn('devices-notification: delete session failed', {
639
+ message: toError(error).message
640
+ });
641
+ });
642
+ }
643
+ }
644
+ // invalidate device list cache so next fanout fetches fresh list
645
+ if (sessionStore.deviceList) {
646
+ await sessionStore.deviceList.deleteUserDevices(userJid).catch((error) => {
647
+ logger.warn('devices-notification: invalidate cache failed', {
648
+ message: toError(error).message
649
+ });
650
+ });
651
+ }
652
+ // for update notifications, re-sync immediately
653
+ if (parsed.action === DEVICE_NOTIFICATION_ACTIONS.UPDATE) {
654
+ signalDeviceSync.syncDeviceList([userJid]).catch((error) => {
655
+ logger.warn('devices-notification: sync device list failed', {
656
+ message: toError(error).message
657
+ });
658
+ });
659
+ }
660
+ runtime.emitEvent('notification', {
661
+ rawNode: node,
662
+ stanzaId: parsed.stanzaId,
663
+ chatJid: parsed.fromJid,
664
+ stanzaType: 'devices',
665
+ notificationType: 'devices',
666
+ classification: 'core',
667
+ details: {
668
+ kind: 'device_list_change',
669
+ action: parsed.action,
670
+ devices: parsed.devices
671
+ }
672
+ });
673
+ return true;
674
+ }
675
+ });
676
+ incomingNode.registerIncomingHandler({
677
+ tag: WA_NODE_TAGS.NOTIFICATION,
678
+ subtype: WA_PRIVACY_TOKEN_NOTIFICATION_TYPE,
679
+ prepend: true,
680
+ handler: async (node) => {
681
+ const fromJid = node.attrs.from ?? node.attrs.sender_lid;
682
+ if (!fromJid) {
683
+ return false;
684
+ }
685
+ const tokens = parsePrivacyTokenNotification(node);
686
+ if (tokens.length === 0) {
687
+ return false;
688
+ }
689
+ await trustedContactToken.handleIncomingToken(fromJid, tokens);
690
+ const ackNode = buildAckNode({
691
+ kind: 'notification',
692
+ node,
693
+ typeOverride: WA_PRIVACY_TOKEN_NOTIFICATION_TYPE
694
+ });
695
+ await runtime.sendNode(ackNode);
696
+ return true;
697
+ }
698
+ });
699
+ passiveTasks = new WaPassiveTasksCoordinator({
342
700
  logger,
343
701
  signalStore: sessionStore.signal,
344
702
  signalDigestSync,
345
703
  signalRotateKey,
346
704
  runtime: createPassiveTasksRuntime({
347
- host,
705
+ queryWithContext: runtime.queryWithContext,
348
706
  authClient,
349
707
  nodeOrchestrator,
708
+ receiptQueue,
350
709
  getCurrentCredentials
351
710
  })
352
711
  });
@@ -369,9 +728,17 @@ export function buildWaClientDependencies(input) {
369
728
  messageDispatch,
370
729
  retryCoordinator,
371
730
  appStateSync,
731
+ chatCoordinator: appStateMutations,
372
732
  streamControl,
373
733
  incomingNode,
374
734
  passiveTasks,
375
- groupCoordinator
735
+ groupCoordinator,
736
+ privacyCoordinator,
737
+ profileCoordinator,
738
+ businessCoordinator,
739
+ receiptQueue,
740
+ keyShareCoordinator,
741
+ connectionManager,
742
+ trustedContactToken
376
743
  };
377
744
  }