zapo-js 0.1.2 → 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 (468) hide show
  1. package/README.md +12 -4
  2. package/dist/appstate/WaAppStateCrypto.js +1 -1
  3. package/dist/appstate/WaAppStateSyncClient.js +138 -93
  4. package/dist/appstate/{store/sqlite.js → encoding.js} +13 -8
  5. package/dist/appstate/index.js +8 -6
  6. package/dist/appstate/utils.js +0 -5
  7. package/dist/auth/WaAuthClient.js +36 -47
  8. package/dist/auth/flow/WaAuthCredentialsFlow.js +7 -7
  9. package/dist/auth/index.js +1 -6
  10. package/dist/auth/pairing/WaPairingCodeCrypto.js +6 -4
  11. package/dist/auth/pairing/WaPairingFlow.js +13 -3
  12. package/dist/client/WaClient.js +225 -101
  13. package/dist/client/WaClientFactory.js +294 -44
  14. package/dist/client/connection/WaConnectionManager.js +19 -10
  15. package/dist/client/coordinators/WaBusinessCoordinator.js +241 -0
  16. package/dist/client/coordinators/WaGroupCoordinator.js +11 -7
  17. package/dist/client/coordinators/WaIncomingNodeCoordinator.js +1 -0
  18. package/dist/client/coordinators/WaMessageDispatchCoordinator.js +292 -99
  19. package/dist/client/coordinators/WaPassiveTasksCoordinator.js +74 -31
  20. package/dist/client/coordinators/WaPrivacyCoordinator.js +134 -0
  21. package/dist/client/coordinators/WaProfileCoordinator.js +212 -0
  22. package/dist/client/coordinators/WaRetryCoordinator.js +179 -27
  23. package/dist/client/coordinators/WaStreamControlCoordinator.js +18 -11
  24. package/dist/client/coordinators/WaTrustedContactTokenCoordinator.js +166 -0
  25. package/dist/client/dirty.js +40 -20
  26. package/dist/client/events/devices.js +72 -0
  27. package/dist/client/events/group.js +3 -11
  28. package/dist/client/events/identity.js +22 -0
  29. package/dist/client/events/privacy-token.js +39 -0
  30. package/dist/client/history-sync.js +50 -9
  31. package/dist/client/incoming.js +37 -7
  32. package/dist/client/mailbox.js +24 -23
  33. package/dist/client/messages.js +107 -31
  34. package/dist/client/messaging/fanout.js +21 -11
  35. package/dist/client/messaging/participants.js +6 -4
  36. package/dist/client/persistence/WriteBehindPersistence.js +129 -0
  37. package/dist/client/tokens/cs-token.js +50 -0
  38. package/dist/client/tokens/tc-token.js +25 -0
  39. package/dist/crypto/core/index.js +2 -2
  40. package/dist/crypto/core/keys.js +4 -4
  41. package/dist/crypto/core/nonce.js +2 -0
  42. package/dist/crypto/core/primitives.js +0 -8
  43. package/dist/crypto/core/random.js +22 -0
  44. package/dist/crypto/curves/X25519.js +25 -6
  45. package/dist/crypto/index.js +3 -0
  46. package/dist/crypto/math/constants.js +13 -36
  47. package/dist/crypto/math/edwards.js +171 -44
  48. package/dist/crypto/math/fe.js +706 -0
  49. package/dist/crypto/math/mod.js +10 -3
  50. package/dist/esm/appstate/WaAppStateCrypto.js +1 -1
  51. package/dist/esm/appstate/WaAppStateSyncClient.js +138 -93
  52. package/dist/esm/appstate/{store/sqlite.js → encoding.js} +13 -8
  53. package/dist/esm/appstate/index.js +2 -2
  54. package/dist/esm/appstate/utils.js +2 -5
  55. package/dist/esm/auth/WaAuthClient.js +36 -47
  56. package/dist/esm/auth/flow/WaAuthCredentialsFlow.js +7 -7
  57. package/dist/esm/auth/index.js +0 -2
  58. package/dist/esm/auth/pairing/WaPairingCodeCrypto.js +6 -4
  59. package/dist/esm/auth/pairing/WaPairingFlow.js +14 -4
  60. package/dist/esm/client/WaClient.js +225 -101
  61. package/dist/esm/client/WaClientFactory.js +295 -45
  62. package/dist/esm/client/connection/WaConnectionManager.js +19 -10
  63. package/dist/esm/client/coordinators/WaBusinessCoordinator.js +238 -0
  64. package/dist/esm/client/coordinators/WaGroupCoordinator.js +11 -7
  65. package/dist/esm/client/coordinators/WaIncomingNodeCoordinator.js +1 -0
  66. package/dist/esm/client/coordinators/WaMessageDispatchCoordinator.js +295 -102
  67. package/dist/esm/client/coordinators/WaPassiveTasksCoordinator.js +74 -31
  68. package/dist/esm/client/coordinators/WaPrivacyCoordinator.js +131 -0
  69. package/dist/esm/client/coordinators/WaProfileCoordinator.js +209 -0
  70. package/dist/esm/client/coordinators/WaRetryCoordinator.js +181 -29
  71. package/dist/esm/client/coordinators/WaStreamControlCoordinator.js +19 -12
  72. package/dist/esm/client/coordinators/WaTrustedContactTokenCoordinator.js +162 -0
  73. package/dist/esm/client/dirty.js +40 -20
  74. package/dist/esm/client/events/devices.js +68 -0
  75. package/dist/esm/client/events/group.js +3 -11
  76. package/dist/esm/client/events/identity.js +19 -0
  77. package/dist/esm/client/events/privacy-token.js +36 -0
  78. package/dist/esm/client/history-sync.js +50 -9
  79. package/dist/esm/client/incoming.js +38 -8
  80. package/dist/esm/client/mailbox.js +24 -23
  81. package/dist/esm/client/messages.js +108 -32
  82. package/dist/esm/client/messaging/fanout.js +22 -12
  83. package/dist/esm/client/messaging/participants.js +6 -4
  84. package/dist/esm/client/persistence/WriteBehindPersistence.js +125 -0
  85. package/dist/esm/client/tokens/cs-token.js +46 -0
  86. package/dist/esm/client/tokens/tc-token.js +18 -0
  87. package/dist/esm/crypto/core/index.js +2 -2
  88. package/dist/esm/crypto/core/keys.js +1 -1
  89. package/dist/esm/crypto/core/nonce.js +2 -0
  90. package/dist/esm/crypto/core/primitives.js +0 -7
  91. package/dist/esm/crypto/core/random.js +22 -1
  92. package/dist/esm/crypto/curves/X25519.js +25 -6
  93. package/dist/esm/crypto/index.js +1 -0
  94. package/dist/esm/crypto/math/constants.js +12 -35
  95. package/dist/esm/crypto/math/edwards.js +174 -47
  96. package/dist/esm/crypto/math/fe.js +691 -0
  97. package/dist/esm/crypto/math/mod.js +10 -1
  98. package/dist/esm/index.js +1 -1
  99. package/dist/esm/infra/perf/BackgroundQueue.js +478 -0
  100. package/dist/esm/infra/perf/BoundedTaskQueue.js +3 -1
  101. package/dist/esm/infra/perf/PromiseDedup.js +20 -0
  102. package/dist/esm/infra/perf/SharedExclusiveGate.js +109 -0
  103. package/dist/esm/infra/perf/StoreLock.js +77 -0
  104. package/dist/esm/media/WaMediaCrypto.js +95 -13
  105. package/dist/esm/media/WaMediaTransferClient.js +39 -47
  106. package/dist/esm/media/constants.js +2 -1
  107. package/dist/esm/message/WaMessageClient.js +26 -19
  108. package/dist/esm/message/content.js +195 -9
  109. package/dist/esm/message/icdc.js +76 -0
  110. package/dist/esm/message/incoming.js +24 -12
  111. package/dist/esm/message/phash.js +3 -1
  112. package/dist/esm/message/reporting-token.js +14 -27
  113. package/dist/esm/protocol/appstate.js +9 -40
  114. package/dist/esm/protocol/browser.js +10 -18
  115. package/dist/esm/protocol/constants.js +5 -3
  116. package/dist/esm/protocol/defaults.js +6 -0
  117. package/dist/esm/protocol/index.js +1 -2
  118. package/dist/esm/protocol/jid.js +105 -36
  119. package/dist/esm/protocol/message.js +61 -1
  120. package/dist/esm/protocol/nodes.js +2 -0
  121. package/dist/esm/protocol/notification.js +3 -1
  122. package/dist/esm/protocol/privacy-token.js +17 -0
  123. package/dist/esm/protocol/privacy.js +55 -0
  124. package/dist/esm/protocol/stream.js +26 -1
  125. package/dist/esm/retry/codec.js +216 -0
  126. package/dist/esm/retry/constants.js +1 -1
  127. package/dist/esm/retry/index.js +2 -2
  128. package/dist/esm/retry/parse.js +50 -30
  129. package/dist/esm/retry/replay.js +11 -7
  130. package/dist/esm/retry/tracker.js +50 -12
  131. package/dist/esm/signal/api/SignalDeviceSyncApi.js +49 -32
  132. package/dist/esm/signal/api/SignalDigestSyncApi.js +13 -9
  133. package/dist/esm/signal/api/SignalIdentitySyncApi.js +26 -11
  134. package/dist/esm/signal/api/SignalMissingPreKeysSyncApi.js +18 -7
  135. package/dist/esm/signal/api/SignalRotateKeyApi.js +4 -2
  136. package/dist/esm/signal/api/SignalSessionSyncApi.js +16 -7
  137. package/dist/esm/signal/api/result-map.js +10 -0
  138. package/dist/esm/signal/constants.js +0 -4
  139. package/dist/esm/signal/crypto/WaAdvSignature.js +12 -6
  140. package/dist/esm/signal/{store/sqlite.js → encoding.js} +78 -24
  141. package/dist/esm/signal/group/SenderKeyCodec.js +3 -2
  142. package/dist/esm/signal/group/SenderKeyManager.js +125 -106
  143. package/dist/esm/signal/index.js +1 -0
  144. package/dist/esm/signal/registration/keygen.js +6 -2
  145. package/dist/esm/signal/registration/utils.js +1 -0
  146. package/dist/esm/signal/session/SignalProtocol.js +150 -74
  147. package/dist/esm/signal/session/resolver.js +137 -102
  148. package/dist/esm/store/contracts/privacy-token.store.js +1 -0
  149. package/dist/esm/store/createStore.js +101 -187
  150. package/dist/esm/store/index.js +1 -10
  151. package/dist/esm/store/locks/appstate.lock.js +26 -0
  152. package/dist/esm/store/locks/auth.lock.js +15 -0
  153. package/dist/esm/store/locks/contact.lock.js +20 -0
  154. package/dist/esm/store/locks/device-list.lock.js +20 -0
  155. package/dist/esm/store/locks/message.lock.js +21 -0
  156. package/dist/esm/store/locks/participants.lock.js +20 -0
  157. package/dist/esm/store/locks/privacy-token.lock.js +18 -0
  158. package/dist/esm/store/locks/retry.lock.js +29 -0
  159. package/dist/esm/store/locks/sender-key.lock.js +52 -0
  160. package/dist/esm/store/locks/signal.lock.js +63 -0
  161. package/dist/esm/store/locks/thread.lock.js +21 -0
  162. package/dist/esm/store/noop.store.js +1 -1
  163. package/dist/esm/store/providers/memory/appstate.store.js +22 -24
  164. package/dist/esm/store/providers/memory/device-list.store.js +10 -5
  165. package/dist/esm/store/providers/memory/privacy-token.store.js +43 -0
  166. package/dist/esm/store/providers/memory/retry.store.js +77 -2
  167. package/dist/esm/store/providers/memory/sender-key.store.js +6 -1
  168. package/dist/esm/store/providers/memory/signal.store.js +36 -19
  169. package/dist/esm/transport/WaComms.js +3 -1
  170. package/dist/esm/transport/WaWebSocket.js +0 -6
  171. package/dist/esm/transport/binary/constants.js +0 -30
  172. package/dist/esm/transport/binary/decoder.js +4 -4
  173. package/dist/esm/transport/binary/encoder.js +8 -15
  174. package/dist/esm/transport/binary/index.js +0 -1
  175. package/dist/esm/transport/node/WaNodeOrchestrator.js +25 -19
  176. package/dist/esm/transport/node/builders/business.js +129 -0
  177. package/dist/esm/transport/node/builders/global.js +370 -0
  178. package/dist/esm/transport/node/builders/index.js +5 -2
  179. package/dist/esm/transport/node/builders/message.js +63 -239
  180. package/dist/esm/transport/node/builders/pairing.js +0 -24
  181. package/dist/esm/transport/node/builders/privacy-token.js +41 -0
  182. package/dist/esm/transport/node/builders/privacy.js +48 -0
  183. package/dist/esm/transport/node/builders/profile.js +70 -0
  184. package/dist/esm/transport/node/builders/retry.js +10 -22
  185. package/dist/esm/transport/node/builders/usync.js +6 -2
  186. package/dist/esm/transport/node/helpers.js +19 -1
  187. package/dist/esm/transport/node/usync.js +3 -33
  188. package/dist/esm/transport/node/xml.js +35 -14
  189. package/dist/esm/transport/noise/WaClientPayload.js +10 -10
  190. package/dist/esm/transport/noise/WaNoiseCert.js +3 -3
  191. package/dist/esm/transport/noise/WaNoiseSession.js +64 -23
  192. package/dist/esm/transport/noise/WaNoiseSocket.js +8 -4
  193. package/dist/esm/transport/stream/parse.js +8 -4
  194. package/dist/esm/util/bytes.js +22 -18
  195. package/dist/esm/util/index.js +5 -0
  196. package/dist/esm/util/primitives.js +3 -2
  197. package/dist/index.js +7 -1
  198. package/dist/infra/perf/BackgroundQueue.js +482 -0
  199. package/dist/infra/perf/BoundedTaskQueue.js +3 -1
  200. package/dist/infra/perf/PromiseDedup.js +24 -0
  201. package/dist/infra/perf/SharedExclusiveGate.js +113 -0
  202. package/dist/infra/perf/StoreLock.js +81 -0
  203. package/dist/media/WaMediaCrypto.js +94 -12
  204. package/dist/media/WaMediaTransferClient.js +39 -47
  205. package/dist/media/constants.js +2 -1
  206. package/dist/message/WaMessageClient.js +26 -19
  207. package/dist/message/content.js +198 -9
  208. package/dist/message/icdc.js +81 -0
  209. package/dist/message/incoming.js +24 -12
  210. package/dist/message/phash.js +3 -1
  211. package/dist/message/reporting-token.js +14 -28
  212. package/dist/protocol/appstate.js +10 -41
  213. package/dist/protocol/browser.js +10 -18
  214. package/dist/protocol/constants.js +21 -2
  215. package/dist/protocol/defaults.js +6 -0
  216. package/dist/protocol/index.js +8 -5
  217. package/dist/protocol/jid.js +111 -36
  218. package/dist/protocol/message.js +62 -2
  219. package/dist/protocol/nodes.js +2 -0
  220. package/dist/protocol/notification.js +3 -1
  221. package/dist/protocol/privacy-token.js +20 -0
  222. package/dist/protocol/privacy.js +58 -0
  223. package/dist/protocol/stream.js +27 -2
  224. package/dist/retry/codec.js +220 -0
  225. package/dist/retry/constants.js +1 -1
  226. package/dist/retry/index.js +5 -5
  227. package/dist/retry/parse.js +51 -30
  228. package/dist/retry/replay.js +10 -6
  229. package/dist/retry/tracker.js +50 -12
  230. package/dist/signal/api/SignalDeviceSyncApi.js +48 -31
  231. package/dist/signal/api/SignalDigestSyncApi.js +13 -9
  232. package/dist/signal/api/SignalIdentitySyncApi.js +25 -10
  233. package/dist/signal/api/SignalMissingPreKeysSyncApi.js +17 -6
  234. package/dist/signal/api/SignalRotateKeyApi.js +4 -2
  235. package/dist/signal/api/SignalSessionSyncApi.js +16 -7
  236. package/dist/signal/api/result-map.js +13 -0
  237. package/dist/signal/constants.js +1 -5
  238. package/dist/signal/crypto/WaAdvSignature.js +11 -5
  239. package/dist/signal/{store/sqlite.js → encoding.js} +79 -25
  240. package/dist/signal/group/SenderKeyCodec.js +4 -3
  241. package/dist/signal/group/SenderKeyManager.js +125 -106
  242. package/dist/signal/index.js +13 -1
  243. package/dist/signal/registration/keygen.js +6 -2
  244. package/dist/signal/registration/utils.js +1 -0
  245. package/dist/signal/session/SignalProtocol.js +150 -74
  246. package/dist/signal/session/resolver.js +135 -100
  247. package/dist/store/contracts/privacy-token.store.js +2 -0
  248. package/dist/store/createStore.js +101 -187
  249. package/dist/store/index.js +15 -33
  250. package/dist/store/locks/appstate.lock.js +29 -0
  251. package/dist/store/locks/auth.lock.js +18 -0
  252. package/dist/store/locks/contact.lock.js +23 -0
  253. package/dist/store/locks/device-list.lock.js +23 -0
  254. package/dist/store/locks/message.lock.js +24 -0
  255. package/dist/store/locks/participants.lock.js +23 -0
  256. package/dist/store/locks/privacy-token.lock.js +21 -0
  257. package/dist/store/locks/retry.lock.js +32 -0
  258. package/dist/store/locks/sender-key.lock.js +55 -0
  259. package/dist/store/locks/signal.lock.js +66 -0
  260. package/dist/store/locks/thread.lock.js +24 -0
  261. package/dist/store/noop.store.js +1 -1
  262. package/dist/store/providers/memory/appstate.store.js +22 -24
  263. package/dist/store/providers/memory/device-list.store.js +10 -5
  264. package/dist/store/providers/memory/privacy-token.store.js +47 -0
  265. package/dist/store/providers/memory/retry.store.js +77 -2
  266. package/dist/store/providers/memory/sender-key.store.js +6 -1
  267. package/dist/store/providers/memory/signal.store.js +36 -19
  268. package/dist/transport/WaComms.js +3 -1
  269. package/dist/transport/WaWebSocket.js +0 -6
  270. package/dist/transport/binary/constants.js +1 -31
  271. package/dist/transport/binary/decoder.js +4 -4
  272. package/dist/transport/binary/encoder.js +8 -15
  273. package/dist/transport/binary/index.js +0 -4
  274. package/dist/transport/node/WaNodeOrchestrator.js +24 -18
  275. package/dist/transport/node/builders/business.js +137 -0
  276. package/dist/transport/node/builders/global.js +375 -0
  277. package/dist/transport/node/builders/index.js +18 -9
  278. package/dist/transport/node/builders/message.js +64 -245
  279. package/dist/transport/node/builders/pairing.js +0 -26
  280. package/dist/transport/node/builders/privacy-token.js +46 -0
  281. package/dist/transport/node/builders/privacy.js +55 -0
  282. package/dist/transport/node/builders/profile.js +78 -0
  283. package/dist/transport/node/builders/retry.js +9 -21
  284. package/dist/transport/node/builders/usync.js +6 -2
  285. package/dist/transport/node/helpers.js +20 -1
  286. package/dist/transport/node/usync.js +2 -32
  287. package/dist/transport/node/xml.js +35 -14
  288. package/dist/transport/noise/WaClientPayload.js +13 -13
  289. package/dist/transport/noise/WaNoiseCert.js +2 -2
  290. package/dist/transport/noise/WaNoiseSession.js +64 -23
  291. package/dist/transport/noise/WaNoiseSocket.js +8 -4
  292. package/dist/transport/stream/parse.js +7 -3
  293. package/dist/types/appstate/encoding.d.ts +7 -0
  294. package/dist/types/appstate/index.d.ts +3 -3
  295. package/dist/types/appstate/utils.d.ts +0 -2
  296. package/dist/types/auth/flow/WaAuthCredentialsFlow.d.ts +1 -1
  297. package/dist/types/auth/index.d.ts +0 -2
  298. package/dist/types/auth/types.d.ts +1 -0
  299. package/dist/types/client/WaClient.d.ts +27 -12
  300. package/dist/types/client/WaClientFactory.d.ts +12 -4
  301. package/dist/types/client/connection/WaConnectionManager.d.ts +2 -0
  302. package/dist/types/client/coordinators/WaBusinessCoordinator.d.ts +57 -0
  303. package/dist/types/client/coordinators/WaIncomingNodeCoordinator.d.ts +3 -1
  304. package/dist/types/client/coordinators/WaMessageDispatchCoordinator.d.ts +14 -0
  305. package/dist/types/client/coordinators/WaPassiveTasksCoordinator.d.ts +4 -0
  306. package/dist/types/client/coordinators/WaPrivacyCoordinator.d.ts +26 -0
  307. package/dist/types/client/coordinators/WaProfileCoordinator.d.ts +36 -0
  308. package/dist/types/client/coordinators/WaRetryCoordinator.d.ts +6 -0
  309. package/dist/types/client/coordinators/WaStreamControlCoordinator.d.ts +3 -2
  310. package/dist/types/client/coordinators/WaTrustedContactTokenCoordinator.d.ts +45 -0
  311. package/dist/types/client/events/devices.d.ts +20 -0
  312. package/dist/types/client/events/identity.d.ts +9 -0
  313. package/dist/types/client/events/privacy-token.d.ts +7 -0
  314. package/dist/types/client/history-sync.d.ts +9 -6
  315. package/dist/types/client/incoming.d.ts +3 -1
  316. package/dist/types/client/index.d.ts +1 -1
  317. package/dist/types/client/mailbox.d.ts +3 -5
  318. package/dist/types/client/messages.d.ts +1 -2
  319. package/dist/types/client/persistence/WriteBehindPersistence.d.ts +34 -0
  320. package/dist/types/client/tokens/cs-token.d.ts +10 -0
  321. package/dist/types/client/tokens/tc-token.d.ts +5 -0
  322. package/dist/types/client/types.d.ts +51 -3
  323. package/dist/types/crypto/core/index.d.ts +2 -2
  324. package/dist/types/crypto/core/nonce.d.ts +2 -0
  325. package/dist/types/crypto/core/primitives.d.ts +0 -1
  326. package/dist/types/crypto/core/random.d.ts +1 -0
  327. package/dist/types/crypto/index.d.ts +1 -0
  328. package/dist/types/crypto/math/constants.d.ts +4 -2
  329. package/dist/types/crypto/math/fe.d.ts +30 -0
  330. package/dist/types/crypto/math/mod.d.ts +0 -2
  331. package/dist/types/crypto/math/types.d.ts +11 -4
  332. package/dist/types/index.d.ts +5 -3
  333. package/dist/types/infra/perf/BackgroundQueue.d.ts +58 -0
  334. package/dist/types/infra/perf/PromiseDedup.d.ts +4 -0
  335. package/dist/types/infra/perf/SharedExclusiveGate.d.ts +17 -0
  336. package/dist/types/infra/perf/StoreLock.d.ts +10 -0
  337. package/dist/types/media/WaMediaCrypto.d.ts +3 -2
  338. package/dist/types/media/WaMediaTransferClient.d.ts +3 -12
  339. package/dist/types/media/constants.d.ts +1 -1
  340. package/dist/types/media/index.d.ts +1 -1
  341. package/dist/types/media/types.d.ts +10 -2
  342. package/dist/types/message/content.d.ts +8 -0
  343. package/dist/types/message/icdc.d.ts +13 -0
  344. package/dist/types/message/reporting-token.d.ts +0 -1
  345. package/dist/types/message/types.d.ts +45 -6
  346. package/dist/types/protocol/appstate.d.ts +0 -11
  347. package/dist/types/protocol/constants.d.ts +7 -3
  348. package/dist/types/protocol/defaults.d.ts +6 -0
  349. package/dist/types/protocol/index.d.ts +1 -2
  350. package/dist/types/protocol/jid.d.ts +19 -2
  351. package/dist/types/protocol/message.d.ts +60 -0
  352. package/dist/types/protocol/nodes.d.ts +2 -0
  353. package/dist/types/protocol/notification.d.ts +2 -0
  354. package/dist/types/protocol/privacy-token.d.ts +17 -0
  355. package/dist/types/protocol/privacy.d.ts +75 -0
  356. package/dist/types/protocol/stream.d.ts +30 -0
  357. package/dist/types/retry/codec.d.ts +3 -0
  358. package/dist/types/retry/index.d.ts +3 -3
  359. package/dist/types/retry/parse.d.ts +5 -2
  360. package/dist/types/retry/tracker.d.ts +1 -0
  361. package/dist/types/retry/types.d.ts +6 -1
  362. package/dist/types/signal/api/SignalDeviceSyncApi.d.ts +2 -1
  363. package/dist/types/signal/api/SignalDigestSyncApi.d.ts +6 -0
  364. package/dist/types/signal/api/SignalIdentitySyncApi.d.ts +2 -0
  365. package/dist/types/signal/api/SignalRotateKeyApi.d.ts +4 -5
  366. package/dist/types/signal/api/SignalSessionSyncApi.d.ts +8 -6
  367. package/dist/types/signal/api/result-map.d.ts +1 -0
  368. package/dist/types/signal/constants.d.ts +0 -3
  369. package/dist/types/signal/{store/sqlite.d.ts → encoding.d.ts} +3 -3
  370. package/dist/types/signal/group/SenderKeyManager.d.ts +10 -5
  371. package/dist/types/signal/index.d.ts +2 -0
  372. package/dist/types/signal/session/SignalProtocol.d.ts +10 -4
  373. package/dist/types/signal/session/resolver.d.ts +7 -2
  374. package/dist/types/store/contracts/appstate.store.d.ts +1 -1
  375. package/dist/types/store/contracts/privacy-token.store.d.ts +16 -0
  376. package/dist/types/store/contracts/retry.store.d.ts +7 -0
  377. package/dist/types/store/contracts/signal.store.d.ts +7 -0
  378. package/dist/types/store/createStore.d.ts +1 -1
  379. package/dist/types/store/index.d.ts +5 -13
  380. package/dist/types/store/locks/appstate.lock.d.ts +3 -0
  381. package/dist/types/store/locks/auth.lock.d.ts +3 -0
  382. package/dist/types/store/locks/contact.lock.d.ts +3 -0
  383. package/dist/types/store/locks/device-list.lock.d.ts +2 -0
  384. package/dist/types/store/locks/message.lock.d.ts +3 -0
  385. package/dist/types/store/locks/participants.lock.d.ts +2 -0
  386. package/dist/types/store/locks/privacy-token.lock.d.ts +2 -0
  387. package/dist/types/store/locks/retry.lock.d.ts +2 -0
  388. package/dist/types/store/locks/sender-key.lock.d.ts +3 -0
  389. package/dist/types/store/locks/signal.lock.d.ts +3 -0
  390. package/dist/types/store/locks/thread.lock.d.ts +3 -0
  391. package/dist/types/store/providers/memory/appstate.store.d.ts +1 -1
  392. package/dist/types/store/providers/memory/privacy-token.store.d.ts +13 -0
  393. package/dist/types/store/providers/memory/retry.store.d.ts +8 -0
  394. package/dist/types/store/providers/memory/signal.store.d.ts +2 -1
  395. package/dist/types/store/types.d.ts +49 -61
  396. package/dist/types/transport/WaWebSocket.d.ts +0 -1
  397. package/dist/types/transport/binary/constants.d.ts +0 -30
  398. package/dist/types/transport/binary/index.d.ts +0 -1
  399. package/dist/types/transport/node/WaNodeOrchestrator.d.ts +3 -4
  400. package/dist/types/transport/node/builders/business.d.ts +29 -0
  401. package/dist/types/transport/node/builders/global.d.ts +102 -0
  402. package/dist/types/transport/node/builders/index.d.ts +5 -2
  403. package/dist/types/transport/node/builders/message.d.ts +8 -7
  404. package/dist/types/transport/node/builders/pairing.d.ts +0 -2
  405. package/dist/types/transport/node/builders/privacy-token.d.ts +9 -0
  406. package/dist/types/transport/node/builders/privacy.d.ts +7 -0
  407. package/dist/types/transport/node/builders/profile.d.ts +8 -0
  408. package/dist/types/transport/node/builders/retry.d.ts +0 -1
  409. package/dist/types/transport/node/helpers.d.ts +5 -0
  410. package/dist/types/transport/noise/WaNoiseSession.d.ts +3 -2
  411. package/dist/types/transport/noise/WaNoiseSocket.d.ts +4 -2
  412. package/dist/types/util/bytes.d.ts +1 -1
  413. package/dist/types/util/index.d.ts +5 -0
  414. package/dist/types/util/primitives.d.ts +0 -1
  415. package/dist/util/bytes.js +22 -18
  416. package/dist/util/index.js +23 -0
  417. package/dist/util/primitives.js +2 -2
  418. package/package.json +29 -7
  419. package/proto/index.js +1 -1
  420. package/dist/crypto/core/constants.js +0 -4
  421. package/dist/esm/crypto/core/constants.js +0 -1
  422. package/dist/esm/retry/outbound.js +0 -82
  423. package/dist/esm/store/providers/sqlite/BaseSqliteStore.js +0 -37
  424. package/dist/esm/store/providers/sqlite/appstate.store.js +0 -250
  425. package/dist/esm/store/providers/sqlite/auth.store.js +0 -176
  426. package/dist/esm/store/providers/sqlite/connection.js +0 -245
  427. package/dist/esm/store/providers/sqlite/contact.store.js +0 -74
  428. package/dist/esm/store/providers/sqlite/device-list.store.js +0 -127
  429. package/dist/esm/store/providers/sqlite/message.store.js +0 -132
  430. package/dist/esm/store/providers/sqlite/migrations.js +0 -347
  431. package/dist/esm/store/providers/sqlite/participants.store.js +0 -77
  432. package/dist/esm/store/providers/sqlite/retry.store.js +0 -141
  433. package/dist/esm/store/providers/sqlite/sender-key.store.js +0 -198
  434. package/dist/esm/store/providers/sqlite/signal.store.js +0 -435
  435. package/dist/esm/store/providers/sqlite/table-names.js +0 -107
  436. package/dist/esm/store/providers/sqlite/thread.store.js +0 -85
  437. package/dist/retry/outbound.js +0 -87
  438. package/dist/store/providers/sqlite/BaseSqliteStore.js +0 -41
  439. package/dist/store/providers/sqlite/appstate.store.js +0 -254
  440. package/dist/store/providers/sqlite/auth.store.js +0 -180
  441. package/dist/store/providers/sqlite/connection.js +0 -281
  442. package/dist/store/providers/sqlite/contact.store.js +0 -78
  443. package/dist/store/providers/sqlite/device-list.store.js +0 -131
  444. package/dist/store/providers/sqlite/message.store.js +0 -136
  445. package/dist/store/providers/sqlite/migrations.js +0 -350
  446. package/dist/store/providers/sqlite/participants.store.js +0 -81
  447. package/dist/store/providers/sqlite/retry.store.js +0 -145
  448. package/dist/store/providers/sqlite/sender-key.store.js +0 -202
  449. package/dist/store/providers/sqlite/signal.store.js +0 -439
  450. package/dist/store/providers/sqlite/table-names.js +0 -113
  451. package/dist/store/providers/sqlite/thread.store.js +0 -89
  452. package/dist/types/appstate/store/sqlite.d.ts +0 -7
  453. package/dist/types/crypto/core/constants.d.ts +0 -1
  454. package/dist/types/retry/outbound.d.ts +0 -4
  455. package/dist/types/store/providers/sqlite/BaseSqliteStore.d.ts +0 -12
  456. package/dist/types/store/providers/sqlite/appstate.store.d.ts +0 -17
  457. package/dist/types/store/providers/sqlite/auth.store.d.ts +0 -10
  458. package/dist/types/store/providers/sqlite/connection.d.ts +0 -10
  459. package/dist/types/store/providers/sqlite/contact.store.d.ts +0 -12
  460. package/dist/types/store/providers/sqlite/device-list.store.d.ts +0 -15
  461. package/dist/types/store/providers/sqlite/message.store.d.ts +0 -13
  462. package/dist/types/store/providers/sqlite/migrations.d.ts +0 -3
  463. package/dist/types/store/providers/sqlite/participants.store.d.ts +0 -12
  464. package/dist/types/store/providers/sqlite/retry.store.d.ts +0 -15
  465. package/dist/types/store/providers/sqlite/sender-key.store.d.ts +0 -24
  466. package/dist/types/store/providers/sqlite/signal.store.d.ts +0 -53
  467. package/dist/types/store/providers/sqlite/table-names.d.ts +0 -5
  468. package/dist/types/store/providers/sqlite/thread.store.d.ts +0 -13
@@ -4,13 +4,20 @@ import { WaConnectionManager } from './connection/WaConnectionManager.js';
4
4
  import { WaKeyShareCoordinator } from './connection/WaKeyShareCoordinator.js';
5
5
  import { WaReceiptQueue } from './connection/WaReceiptQueue.js';
6
6
  import { WaAppStateMutationCoordinator } from './coordinators/WaAppStateMutationCoordinator.js';
7
+ import { createBusinessCoordinator } from './coordinators/WaBusinessCoordinator.js';
7
8
  import { createGroupCoordinator } from './coordinators/WaGroupCoordinator.js';
8
9
  import { WaIncomingNodeCoordinator } from './coordinators/WaIncomingNodeCoordinator.js';
9
10
  import { WaMessageDispatchCoordinator } from './coordinators/WaMessageDispatchCoordinator.js';
10
11
  import { WaPassiveTasksCoordinator } from './coordinators/WaPassiveTasksCoordinator.js';
12
+ import { createPrivacyCoordinator } from './coordinators/WaPrivacyCoordinator.js';
13
+ import { createProfileCoordinator } from './coordinators/WaProfileCoordinator.js';
11
14
  import { WaRetryCoordinator } from './coordinators/WaRetryCoordinator.js';
12
15
  import { createStreamControlHandler } from './coordinators/WaStreamControlCoordinator.js';
16
+ import { WaTrustedContactTokenCoordinator } from './coordinators/WaTrustedContactTokenCoordinator.js';
13
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';
14
21
  import { buildMediaMessageContent, getMediaConn as getClientMediaConn } from './messages.js';
15
22
  import { createDeviceFanoutResolver } from './messaging/fanout.js';
16
23
  import { createAppStateSyncKeyProtocol } from './messaging/key-protocol.js';
@@ -18,7 +25,8 @@ import { createGroupParticipantsCache } from './messaging/participants.js';
18
25
  import { WaMediaTransferClient } from '../media/WaMediaTransferClient.js';
19
26
  import { handleIncomingMessageAck } from '../message/incoming.js';
20
27
  import { WaMessageClient } from '../message/WaMessageClient.js';
21
- 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';
22
30
  import { createOutboundRetryTracker } from '../retry/tracker.js';
23
31
  import { SignalDeviceSyncApi } from '../signal/api/SignalDeviceSyncApi.js';
24
32
  import { SignalDigestSyncApi } from '../signal/api/SignalDigestSyncApi.js';
@@ -30,6 +38,8 @@ import { SenderKeyManager } from '../signal/group/SenderKeyManager.js';
30
38
  import { createSignalSessionResolver } from '../signal/session/resolver.js';
31
39
  import { SignalProtocol } from '../signal/session/SignalProtocol.js';
32
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';
33
43
  import { createUsyncSidGenerator } from '../transport/node/usync.js';
34
44
  import { WaNodeOrchestrator } from '../transport/node/WaNodeOrchestrator.js';
35
45
  import { WaNodeTransport } from '../transport/node/WaNodeTransport.js';
@@ -90,31 +100,6 @@ export function resolveWaClientBase(options, logger) {
90
100
  sessionStore
91
101
  };
92
102
  }
93
- function createIncomingMessageAckOptions(input) {
94
- const { logger, sendNode, emitEvent, handleIncomingMessageEvent, handleError, getCurrentMeJid, signalProtocol, senderKeyManager, retryCoordinator } = input;
95
- return {
96
- logger,
97
- sendNode,
98
- getMeJid: getCurrentMeJid,
99
- signalProtocol,
100
- senderKeyManager,
101
- onDecryptFailure: (context, error) => retryCoordinator.onDecryptFailure(context, error),
102
- emitIncomingMessage: (event) => {
103
- void handleIncomingMessageEvent(event).catch((err) => handleError(toError(err)));
104
- },
105
- emitUnhandledStanza: (event) => emitEvent('stanza_unhandled', event)
106
- };
107
- }
108
- function createHandleClientDirtyBits(input) {
109
- const { logger, queryWithContext, syncAppState, getCurrentCredentials, generateUsyncSid } = input;
110
- return (dirtyBits) => handleDirtyBits({
111
- logger,
112
- queryWithContext,
113
- getCurrentCredentials,
114
- syncAppState,
115
- generateUsyncSid
116
- }, dirtyBits);
117
- }
118
103
  function createIncomingNodeRuntime(input) {
119
104
  const { logger, emitEvent, authClient, connectionManager, nodeOrchestrator, streamControl, mediaMessageBuildOptions, retryCoordinator, messageDispatch, sendNode, syncAppState, disconnect, clearStoredCredentials, getCurrentMeJid, handleClientDirtyBits, incomingMessageAckOptions } = input;
120
105
  return {
@@ -156,6 +141,9 @@ function createIncomingNodeRuntime(input) {
156
141
  },
157
142
  emitUnhandledIncomingNode: (event) => emitEvent('stanza_unhandled', event),
158
143
  syncAppState,
144
+ stopComms: () => {
145
+ void connectionManager.getComms()?.stopComms();
146
+ },
159
147
  disconnect,
160
148
  clearStoredCredentials,
161
149
  parseDirtyBits: (nodes) => parseDirtyBits(nodes, logger),
@@ -272,7 +260,8 @@ export function buildWaClientDependencies(input) {
272
260
  deviceBrowser: options.deviceBrowser,
273
261
  deviceOsDisplayName: options.deviceOsDisplayName,
274
262
  devicePlatform: options.devicePlatform,
275
- requireFullSync: options.requireFullSync
263
+ requireFullSync: options.requireFullSync,
264
+ version: options.version
276
265
  }, {
277
266
  logger,
278
267
  authStore: sessionStore.auth,
@@ -299,6 +288,16 @@ export function buildWaClientDependencies(input) {
299
288
  const groupCoordinator = createGroupCoordinator({
300
289
  queryWithContext: runtime.queryWithContext
301
290
  });
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
+ });
302
301
  const retryTracker = createOutboundRetryTracker({
303
302
  retryStore: sessionStore.retry,
304
303
  logger
@@ -318,9 +317,30 @@ export function buildWaClientDependencies(input) {
318
317
  });
319
318
  const participantsCache = createGroupParticipantsCache({
320
319
  participantsStore: sessionStore.participants,
321
- queryGroupParticipantJids: async (groupJid) => (await groupCoordinator.queryGroupMetadata(groupJid)).participants.map((participant) => participant.jid),
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
+ },
322
328
  logger
323
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
+ });
324
344
  let messageDispatch;
325
345
  const appStateSyncKeyProtocol = createAppStateSyncKeyProtocol({
326
346
  publishSignalMessage: (signalInput, publishOptions) => messageDispatch.publishSignalMessage(signalInput, publishOptions),
@@ -340,9 +360,18 @@ export function buildWaClientDependencies(input) {
340
360
  buildMessageContent: async (content) => buildMediaMessageContent(mediaMessageBuildOptions, content),
341
361
  senderKeyManager,
342
362
  signalProtocol,
363
+ signalStore: sessionStore.signal,
364
+ deviceListStore: sessionStore.deviceList,
343
365
  getCurrentMeJid,
344
366
  getCurrentMeLid,
345
- 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
+ }
346
375
  });
347
376
  const retryCoordinator = new WaRetryCoordinator({
348
377
  logger,
@@ -387,14 +416,27 @@ export function buildWaClientDependencies(input) {
387
416
  connectionManager.setMediaConnCache(mediaConnCacheFallback);
388
417
  }
389
418
  scheduleReconnectAfterPairing = () => connectionManager?.scheduleReconnectAfterPairing();
390
- const disconnectWithClientSideEffects = async () => {
419
+ const disconnectWithClientSideEffects = async (reason, isLogout, code) => {
391
420
  keyShareCoordinator.notifyDisconnected();
392
421
  await connectionManager?.disconnect();
393
- runtime.emitEvent('connection_close', {});
422
+ runtime.emitEvent('connection', {
423
+ status: 'close',
424
+ reason,
425
+ code,
426
+ isLogout,
427
+ isNewLogin: false
428
+ });
394
429
  };
395
- const connectWithClientSideEffects = async () => {
430
+ const connectWithClientSideEffects = async (reason) => {
431
+ runtime.resumeIncomingEvents();
396
432
  await connectionManager?.connect(runtime.handleIncomingFrame);
397
- runtime.emitEvent('connection_open', {});
433
+ runtime.emitEvent('connection', {
434
+ status: 'open',
435
+ reason,
436
+ code: null,
437
+ isLogout: false,
438
+ isNewLogin: connectionManager?.wasNewLogin() ?? false
439
+ });
398
440
  };
399
441
  const clearStoredCredentialsWithClientSideEffects = async () => {
400
442
  await connectionManager?.clearStoredCredentials();
@@ -411,24 +453,27 @@ export function buildWaClientDependencies(input) {
411
453
  clearStoredCredentials: clearStoredCredentialsWithClientSideEffects,
412
454
  connect: connectWithClientSideEffects
413
455
  });
414
- const incomingMessageAckOptions = createIncomingMessageAckOptions({
456
+ const incomingMessageAckOptions = {
415
457
  logger,
416
458
  sendNode: runtime.sendNode,
417
- emitEvent: runtime.emitEvent,
418
- handleIncomingMessageEvent: runtime.handleIncomingMessageEvent,
419
- handleError: runtime.handleError,
420
- getCurrentMeJid,
459
+ getMeJid: getCurrentMeJid,
421
460
  signalProtocol,
422
461
  senderKeyManager,
423
- retryCoordinator
424
- });
425
- 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({
426
471
  logger,
427
472
  queryWithContext: runtime.queryWithContext,
428
- syncAppState: runtime.syncAppState,
429
473
  getCurrentCredentials,
474
+ syncAppState: runtime.syncAppState,
430
475
  generateUsyncSid
431
- });
476
+ }, dirtyBits);
432
477
  const incomingNode = new WaIncomingNodeCoordinator({
433
478
  logger,
434
479
  runtime: createIncomingNodeRuntime({
@@ -450,6 +495,207 @@ export function buildWaClientDependencies(input) {
450
495
  incomingMessageAckOptions
451
496
  })
452
497
  });
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
+ });
453
699
  passiveTasks = new WaPassiveTasksCoordinator({
454
700
  logger,
455
701
  signalStore: sessionStore.signal,
@@ -482,13 +728,17 @@ export function buildWaClientDependencies(input) {
482
728
  messageDispatch,
483
729
  retryCoordinator,
484
730
  appStateSync,
485
- appStateMutations,
731
+ chatCoordinator: appStateMutations,
486
732
  streamControl,
487
733
  incomingNode,
488
734
  passiveTasks,
489
735
  groupCoordinator,
736
+ privacyCoordinator,
737
+ profileCoordinator,
738
+ businessCoordinator,
490
739
  receiptQueue,
491
740
  keyShareCoordinator,
492
- connectionManager
741
+ connectionManager,
742
+ trustedContactToken
493
743
  };
494
744
  }
@@ -2,6 +2,7 @@ import { WaComms } from '../../transport/WaComms.js';
2
2
  import { toError } from '../../util/primitives.js';
3
3
  export class WaConnectionManager {
4
4
  constructor(options) {
5
+ this.lastConnectWasNewLogin = false;
5
6
  this.logger = options.logger;
6
7
  this.options = options.options;
7
8
  this.authClient = options.authClient;
@@ -30,11 +31,12 @@ export class WaConnectionManager {
30
31
  const operation = this.runLifecycleOperation(async () => {
31
32
  await this.connectInternal(frameHandler, lifecycleGeneration);
32
33
  });
33
- this.connectPromise = operation.finally(() => {
34
- if (this.connectPromise === operation) {
34
+ const promise = operation.finally(() => {
35
+ if (this.connectPromise === promise) {
35
36
  this.connectPromise = null;
36
37
  }
37
38
  });
39
+ this.connectPromise = promise;
38
40
  return this.connectPromise;
39
41
  }
40
42
  scheduleReconnectAfterPairing() {
@@ -64,6 +66,9 @@ export class WaConnectionManager {
64
66
  isConnected() {
65
67
  return !!(this.comms && this.comms.getCommsState().connected);
66
68
  }
69
+ wasNewLogin() {
70
+ return this.lastConnectWasNewLogin;
71
+ }
67
72
  getComms() {
68
73
  return this.comms;
69
74
  }
@@ -93,6 +98,7 @@ export class WaConnectionManager {
93
98
  }
94
99
  this.logger.info('wa client connect start');
95
100
  let credentials = await this.authClient.loadOrCreateCredentials();
101
+ this.lastConnectWasNewLogin = !credentials.meJid;
96
102
  this.assertLifecycleCurrent(lifecycleGeneration, 'connect');
97
103
  try {
98
104
  await this.startCommsWithCredentials(credentials, frameHandler, lifecycleGeneration);
@@ -127,11 +133,12 @@ export class WaConnectionManager {
127
133
  const operation = this.runLifecycleOperation(async () => {
128
134
  await this.reconnectAsRegisteredAfterPairingInternal();
129
135
  });
130
- this.pairingReconnectPromise = operation.finally(() => {
131
- if (this.pairingReconnectPromise === operation) {
136
+ const promise = operation.finally(() => {
137
+ if (this.pairingReconnectPromise === promise) {
132
138
  this.pairingReconnectPromise = null;
133
139
  }
134
140
  });
141
+ this.pairingReconnectPromise = promise;
135
142
  return this.pairingReconnectPromise;
136
143
  }
137
144
  async reconnectAsRegisteredAfterPairingInternal() {
@@ -176,12 +183,14 @@ export class WaConnectionManager {
176
183
  this.pendingComms = null;
177
184
  this.clearCommsBinding(currentComms ?? undefined);
178
185
  await this.authClient.clearTransientState();
179
- if (pendingComms) {
180
- await this.stopCommsQuietly(pendingComms, 'failed to stop pending comms during disconnect');
181
- }
182
- if (currentComms) {
183
- await this.stopCommsQuietly(currentComms, 'failed to stop comms during disconnect');
184
- }
186
+ await Promise.all([
187
+ pendingComms && pendingComms !== currentComms
188
+ ? this.stopCommsQuietly(pendingComms, 'failed to stop pending comms during disconnect')
189
+ : Promise.resolve(),
190
+ currentComms
191
+ ? this.stopCommsQuietly(currentComms, 'failed to stop comms during disconnect')
192
+ : Promise.resolve()
193
+ ]);
185
194
  if (this.isLifecycleCurrent(lifecycleGeneration)) {
186
195
  this.logger.info('wa client disconnected');
187
196
  }