zapo-js 0.1.2 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (630) hide show
  1. package/README.md +16 -4
  2. package/dist/appstate/WaAppStateCrypto.js +50 -42
  3. package/dist/appstate/WaAppStateSyncClient.js +215 -133
  4. package/dist/appstate/{store/sqlite.js → encoding.js} +13 -8
  5. package/dist/appstate/index.js +9 -7
  6. package/dist/appstate/utils.js +0 -5
  7. package/dist/auth/WaAuthClient.js +55 -57
  8. package/dist/auth/credentials-flow.js +195 -0
  9. package/dist/auth/index.js +1 -6
  10. package/dist/auth/pairing/WaPairingFlow.js +39 -32
  11. package/dist/auth/pairing/{WaPairingCodeCrypto.js → pairing-code-crypto.js} +35 -17
  12. package/dist/client/WaClient.js +338 -174
  13. package/dist/client/WaClientFactory.js +399 -66
  14. package/dist/client/connection/WaConnectionManager.js +23 -11
  15. package/dist/client/coordinators/WaAbPropsCoordinator.js +141 -0
  16. package/dist/client/coordinators/WaBusinessCoordinator.js +232 -0
  17. package/dist/client/coordinators/WaEmailCoordinator.js +63 -0
  18. package/dist/client/coordinators/WaGroupCoordinator.js +11 -7
  19. package/dist/client/coordinators/WaIncomingNodeCoordinator.js +34 -8
  20. package/dist/client/coordinators/WaMessageDispatchCoordinator.js +341 -118
  21. package/dist/client/coordinators/WaOfflineResumeCoordinator.js +114 -0
  22. package/dist/client/coordinators/WaPassiveTasksCoordinator.js +97 -36
  23. package/dist/client/coordinators/WaPrivacyCoordinator.js +134 -0
  24. package/dist/client/coordinators/WaProfileCoordinator.js +214 -0
  25. package/dist/client/coordinators/WaRetryCoordinator.js +184 -30
  26. package/dist/client/coordinators/WaStreamControlCoordinator.js +18 -11
  27. package/dist/client/coordinators/WaTrustedContactTokenCoordinator.js +184 -0
  28. package/dist/client/dirty.js +41 -21
  29. package/dist/client/events/abprops.js +43 -0
  30. package/dist/client/events/devices.js +72 -0
  31. package/dist/client/events/group.js +3 -11
  32. package/dist/client/events/identity.js +22 -0
  33. package/dist/client/events/privacy-token.js +38 -0
  34. package/dist/client/events/registration.js +42 -0
  35. package/dist/client/history-sync.js +50 -9
  36. package/dist/client/incoming.js +74 -7
  37. package/dist/client/mailbox.js +40 -23
  38. package/dist/client/media.js +243 -0
  39. package/dist/client/messages.js +245 -92
  40. package/dist/client/messaging/fanout.js +21 -11
  41. package/dist/client/messaging/participants.js +6 -4
  42. package/dist/client/persistence/WriteBehindPersistence.js +129 -0
  43. package/dist/client/tokens/cs-token.js +50 -0
  44. package/dist/client/tokens/tc-token.js +25 -0
  45. package/dist/crypto/core/index.js +5 -2
  46. package/dist/crypto/core/keys.js +4 -4
  47. package/dist/crypto/core/nonce.js +2 -0
  48. package/dist/crypto/core/primitives.js +0 -8
  49. package/dist/crypto/core/random.js +24 -8
  50. package/dist/crypto/core/xeddsa.js +57 -0
  51. package/dist/crypto/curves/X25519.js +43 -6
  52. package/dist/crypto/curves/constants.js +2 -1
  53. package/dist/crypto/index.js +3 -0
  54. package/dist/crypto/math/constants.js +13 -36
  55. package/dist/crypto/math/edwards.js +171 -44
  56. package/dist/crypto/math/fe.js +706 -0
  57. package/dist/crypto/math/mod.js +10 -3
  58. package/dist/esm/appstate/WaAppStateCrypto.js +40 -32
  59. package/dist/esm/appstate/WaAppStateSyncClient.js +206 -124
  60. package/dist/esm/appstate/{store/sqlite.js → encoding.js} +13 -8
  61. package/dist/esm/appstate/index.js +2 -2
  62. package/dist/esm/appstate/{WaAppStateSyncResponseParser.js → response-parser.js} +1 -1
  63. package/dist/esm/appstate/utils.js +2 -5
  64. package/dist/esm/auth/WaAuthClient.js +52 -54
  65. package/dist/esm/auth/credentials-flow.js +190 -0
  66. package/dist/esm/auth/index.js +0 -2
  67. package/dist/esm/auth/pairing/WaPairingFlow.js +39 -32
  68. package/dist/esm/auth/pairing/{WaPairingCodeCrypto.js → pairing-code-crypto.js} +26 -10
  69. package/dist/esm/client/WaClient.js +339 -175
  70. package/dist/esm/client/WaClientFactory.js +401 -68
  71. package/dist/esm/client/connection/WaConnectionManager.js +23 -11
  72. package/dist/esm/client/coordinators/WaAbPropsCoordinator.js +137 -0
  73. package/dist/esm/client/coordinators/WaBusinessCoordinator.js +229 -0
  74. package/dist/esm/client/coordinators/WaEmailCoordinator.js +60 -0
  75. package/dist/esm/client/coordinators/WaGroupCoordinator.js +11 -7
  76. package/dist/esm/client/coordinators/WaIncomingNodeCoordinator.js +36 -10
  77. package/dist/esm/client/coordinators/WaMessageDispatchCoordinator.js +337 -114
  78. package/dist/esm/client/coordinators/WaOfflineResumeCoordinator.js +110 -0
  79. package/dist/esm/client/coordinators/WaPassiveTasksCoordinator.js +97 -36
  80. package/dist/esm/client/coordinators/WaPrivacyCoordinator.js +131 -0
  81. package/dist/esm/client/coordinators/WaProfileCoordinator.js +211 -0
  82. package/dist/esm/client/coordinators/WaRetryCoordinator.js +186 -32
  83. package/dist/esm/client/coordinators/WaStreamControlCoordinator.js +19 -12
  84. package/dist/esm/client/coordinators/WaTrustedContactTokenCoordinator.js +180 -0
  85. package/dist/esm/client/dirty.js +41 -21
  86. package/dist/esm/client/events/abprops.js +40 -0
  87. package/dist/esm/client/events/devices.js +68 -0
  88. package/dist/esm/client/events/group.js +3 -11
  89. package/dist/esm/client/events/identity.js +19 -0
  90. package/dist/esm/client/events/privacy-token.js +35 -0
  91. package/dist/esm/client/events/registration.js +39 -0
  92. package/dist/esm/client/history-sync.js +50 -9
  93. package/dist/esm/client/incoming.js +74 -8
  94. package/dist/esm/client/mailbox.js +40 -23
  95. package/dist/esm/client/media.js +234 -0
  96. package/dist/esm/client/messages.js +244 -91
  97. package/dist/esm/client/messaging/fanout.js +22 -12
  98. package/dist/esm/client/messaging/participants.js +6 -4
  99. package/dist/esm/client/persistence/WriteBehindPersistence.js +125 -0
  100. package/dist/esm/client/tokens/cs-token.js +46 -0
  101. package/dist/esm/client/tokens/tc-token.js +18 -0
  102. package/dist/esm/crypto/core/index.js +3 -2
  103. package/dist/esm/crypto/core/keys.js +1 -1
  104. package/dist/esm/crypto/core/nonce.js +2 -0
  105. package/dist/esm/crypto/core/primitives.js +0 -7
  106. package/dist/esm/crypto/core/random.js +23 -7
  107. package/dist/esm/crypto/core/xeddsa.js +53 -0
  108. package/dist/esm/crypto/curves/X25519.js +45 -8
  109. package/dist/esm/crypto/curves/constants.js +1 -0
  110. package/dist/esm/crypto/index.js +1 -0
  111. package/dist/esm/crypto/math/constants.js +12 -35
  112. package/dist/esm/crypto/math/edwards.js +174 -47
  113. package/dist/esm/crypto/math/fe.js +691 -0
  114. package/dist/esm/crypto/math/mod.js +10 -1
  115. package/dist/esm/index.js +1 -1
  116. package/dist/esm/infra/perf/BackgroundQueue.js +478 -0
  117. package/dist/esm/infra/perf/BoundedTaskQueue.js +3 -1
  118. package/dist/esm/infra/perf/PromiseDedup.js +20 -0
  119. package/dist/esm/infra/perf/SharedExclusiveGate.js +109 -0
  120. package/dist/esm/infra/perf/StoreLock.js +80 -0
  121. package/dist/esm/media/WaMediaCrypto.js +332 -55
  122. package/dist/esm/media/WaMediaTransferClient.js +69 -220
  123. package/dist/esm/media/constants.js +4 -1
  124. package/dist/esm/media/processor.js +1 -0
  125. package/dist/esm/message/WaMessageClient.js +26 -19
  126. package/dist/esm/message/addon-crypto.js +130 -3
  127. package/dist/esm/message/content.js +206 -14
  128. package/dist/esm/message/icdc.js +76 -0
  129. package/dist/esm/message/incoming.js +38 -24
  130. package/dist/esm/message/phash.js +35 -13
  131. package/dist/esm/message/reporting-token.js +17 -30
  132. package/dist/esm/message/use-case-secret.js +1 -1
  133. package/dist/esm/protocol/abprops.js +159 -0
  134. package/dist/esm/protocol/appstate.js +9 -40
  135. package/dist/esm/protocol/browser.js +24 -18
  136. package/dist/esm/protocol/constants.js +8 -4
  137. package/dist/esm/protocol/defaults.js +6 -0
  138. package/dist/esm/protocol/email.js +30 -0
  139. package/dist/esm/protocol/index.js +1 -2
  140. package/dist/esm/protocol/jid.js +142 -39
  141. package/dist/esm/protocol/message.js +61 -1
  142. package/dist/esm/protocol/nodes.js +8 -2
  143. package/dist/esm/protocol/notification.js +9 -1
  144. package/dist/esm/protocol/privacy-token.js +17 -0
  145. package/dist/esm/protocol/privacy.js +55 -0
  146. package/dist/esm/protocol/stream.js +26 -1
  147. package/dist/esm/retry/codec.js +216 -0
  148. package/dist/esm/retry/constants.js +1 -1
  149. package/dist/esm/retry/index.js +2 -2
  150. package/dist/esm/retry/parse.js +50 -30
  151. package/dist/esm/retry/reason.js +1 -1
  152. package/dist/esm/retry/replay.js +11 -7
  153. package/dist/esm/retry/tracker.js +50 -12
  154. package/dist/esm/signal/api/SignalDeviceSyncApi.js +52 -32
  155. package/dist/esm/signal/api/SignalDigestSyncApi.js +21 -15
  156. package/dist/esm/signal/api/SignalIdentitySyncApi.js +30 -15
  157. package/dist/esm/signal/api/SignalMissingPreKeysSyncApi.js +19 -8
  158. package/dist/esm/signal/api/SignalRotateKeyApi.js +4 -2
  159. package/dist/esm/signal/api/SignalSessionSyncApi.js +17 -8
  160. package/dist/esm/signal/api/result-map.js +10 -0
  161. package/dist/esm/signal/constants.js +0 -4
  162. package/dist/esm/signal/crypto/WaAdvSignature.js +5 -45
  163. package/dist/esm/signal/crypto/constants.js +0 -4
  164. package/dist/esm/signal/{store/sqlite.js → encoding.js} +40 -29
  165. package/dist/esm/signal/group/SenderKeyChain.js +3 -3
  166. package/dist/esm/signal/group/SenderKeyCodec.js +8 -8
  167. package/dist/esm/signal/group/SenderKeyManager.js +131 -109
  168. package/dist/esm/signal/index.js +1 -0
  169. package/dist/esm/signal/registration/keygen.js +8 -5
  170. package/dist/esm/signal/registration/utils.js +3 -2
  171. package/dist/esm/signal/session/SignalProtocol.js +158 -81
  172. package/dist/esm/signal/session/SignalRatchet.js +21 -10
  173. package/dist/esm/signal/session/SignalSerializer.js +5 -6
  174. package/dist/esm/signal/session/SignalSession.js +11 -9
  175. package/dist/esm/signal/session/resolver.js +140 -105
  176. package/dist/esm/store/contracts/identity.store.js +1 -0
  177. package/dist/esm/store/contracts/message-secret.store.js +1 -0
  178. package/dist/esm/store/contracts/pre-key.store.js +1 -0
  179. package/dist/esm/store/contracts/privacy-token.store.js +1 -0
  180. package/dist/esm/store/contracts/session.store.js +1 -0
  181. package/dist/esm/store/createStore.js +143 -193
  182. package/dist/esm/store/index.js +5 -10
  183. package/dist/esm/store/locks/appstate.lock.js +26 -0
  184. package/dist/esm/store/locks/auth.lock.js +15 -0
  185. package/dist/esm/store/locks/contact.lock.js +20 -0
  186. package/dist/esm/store/locks/device-list.lock.js +20 -0
  187. package/dist/esm/store/locks/identity.lock.js +16 -0
  188. package/dist/esm/store/locks/message-secret.lock.js +17 -0
  189. package/dist/esm/store/locks/message.lock.js +21 -0
  190. package/dist/esm/store/locks/participants.lock.js +20 -0
  191. package/dist/esm/store/locks/pre-key.lock.js +27 -0
  192. package/dist/esm/store/locks/privacy-token.lock.js +18 -0
  193. package/dist/esm/store/locks/retry.lock.js +29 -0
  194. package/dist/esm/store/locks/sender-key.lock.js +52 -0
  195. package/dist/esm/store/locks/session.lock.js +19 -0
  196. package/dist/esm/store/locks/signal.lock.js +39 -0
  197. package/dist/esm/store/locks/thread.lock.js +21 -0
  198. package/dist/esm/store/noop.store.js +21 -1
  199. package/dist/esm/store/providers/memory/appstate.store.js +22 -24
  200. package/dist/esm/store/providers/memory/device-list.store.js +13 -5
  201. package/dist/esm/store/providers/memory/identity.store.js +31 -0
  202. package/dist/esm/store/providers/memory/message-secret.store.js +81 -0
  203. package/dist/esm/store/providers/memory/participants.store.js +3 -0
  204. package/dist/esm/store/providers/memory/pre-key.store.js +97 -0
  205. package/dist/esm/store/providers/memory/privacy-token.store.js +43 -0
  206. package/dist/esm/store/providers/memory/retry.store.js +99 -10
  207. package/dist/esm/store/providers/memory/sender-key.store.js +6 -1
  208. package/dist/esm/store/providers/memory/session.store.js +45 -0
  209. package/dist/esm/store/providers/memory/signal.store.js +1 -147
  210. package/dist/esm/transport/WaComms.js +7 -4
  211. package/dist/esm/transport/WaWebSocket.js +9 -7
  212. package/dist/esm/transport/binary/constants.js +0 -30
  213. package/dist/esm/transport/binary/decoder.js +4 -4
  214. package/dist/esm/transport/binary/encoder.js +8 -15
  215. package/dist/esm/transport/binary/index.js +0 -1
  216. package/dist/esm/transport/index.js +6 -0
  217. package/dist/esm/transport/keepalive/WaKeepAlive.js +17 -8
  218. package/dist/esm/transport/node/WaMobileTcpSocket.js +114 -0
  219. package/dist/esm/transport/node/WaNodeOrchestrator.js +37 -22
  220. package/dist/esm/transport/node/builders/abprops.js +20 -0
  221. package/dist/esm/transport/node/builders/business.js +129 -0
  222. package/dist/esm/transport/node/builders/device.js +11 -0
  223. package/dist/esm/transport/node/builders/email.js +65 -0
  224. package/dist/esm/transport/node/builders/global.js +370 -0
  225. package/dist/esm/transport/node/builders/message.js +63 -239
  226. package/dist/esm/transport/node/builders/offline.js +14 -0
  227. package/dist/esm/transport/node/builders/pairing.js +0 -24
  228. package/dist/esm/transport/node/builders/prekeys.js +37 -40
  229. package/dist/esm/transport/node/builders/presence.js +13 -0
  230. package/dist/esm/transport/node/builders/privacy-token.js +37 -0
  231. package/dist/esm/transport/node/builders/privacy.js +48 -0
  232. package/dist/esm/transport/node/builders/profile.js +70 -0
  233. package/dist/esm/transport/node/builders/retry.js +11 -23
  234. package/dist/esm/transport/node/builders/usync.js +6 -2
  235. package/dist/esm/transport/node/helpers.js +43 -1
  236. package/dist/esm/transport/node/mex/argo-decoder.js +152 -0
  237. package/dist/esm/transport/node/mex/client.js +83 -0
  238. package/dist/esm/transport/node/mex/persist-ids.js +10 -0
  239. package/dist/esm/transport/node/usync.js +3 -33
  240. package/dist/esm/transport/node/xml.js +35 -14
  241. package/dist/esm/transport/noise/WaClientPayload.js +24 -19
  242. package/dist/esm/transport/noise/WaFrameCodec.js +2 -2
  243. package/dist/esm/transport/noise/WaMobileClientPayload.js +53 -0
  244. package/dist/esm/transport/noise/WaNoiseCert.js +9 -27
  245. package/dist/esm/transport/noise/WaNoiseSession.js +76 -34
  246. package/dist/esm/transport/noise/WaNoiseSocket.js +8 -4
  247. package/dist/esm/transport/stream/parse.js +8 -4
  248. package/dist/esm/util/bytes.js +22 -18
  249. package/dist/esm/util/index.js +5 -0
  250. package/dist/esm/util/primitives.js +3 -2
  251. package/dist/index.js +7 -1
  252. package/dist/infra/perf/BackgroundQueue.js +482 -0
  253. package/dist/infra/perf/BoundedTaskQueue.js +3 -1
  254. package/dist/infra/perf/PromiseDedup.js +24 -0
  255. package/dist/infra/perf/SharedExclusiveGate.js +113 -0
  256. package/dist/infra/perf/StoreLock.js +84 -0
  257. package/dist/media/WaMediaCrypto.js +328 -51
  258. package/dist/media/WaMediaTransferClient.js +72 -253
  259. package/dist/media/constants.js +5 -2
  260. package/dist/media/processor.js +2 -0
  261. package/dist/message/WaMessageClient.js +26 -19
  262. package/dist/message/addon-crypto.js +131 -0
  263. package/dist/message/content.js +211 -14
  264. package/dist/message/icdc.js +81 -0
  265. package/dist/message/incoming.js +38 -24
  266. package/dist/message/phash.js +35 -13
  267. package/dist/message/reporting-token.js +16 -30
  268. package/dist/message/use-case-secret.js +1 -1
  269. package/dist/protocol/abprops.js +163 -0
  270. package/dist/protocol/appstate.js +10 -41
  271. package/dist/protocol/browser.js +25 -18
  272. package/dist/protocol/constants.js +33 -2
  273. package/dist/protocol/defaults.js +6 -0
  274. package/dist/protocol/email.js +33 -0
  275. package/dist/protocol/index.js +8 -5
  276. package/dist/protocol/jid.js +149 -39
  277. package/dist/protocol/message.js +62 -2
  278. package/dist/protocol/nodes.js +8 -2
  279. package/dist/protocol/notification.js +10 -2
  280. package/dist/protocol/privacy-token.js +20 -0
  281. package/dist/protocol/privacy.js +58 -0
  282. package/dist/protocol/stream.js +27 -2
  283. package/dist/retry/codec.js +220 -0
  284. package/dist/retry/constants.js +1 -1
  285. package/dist/retry/index.js +5 -5
  286. package/dist/retry/parse.js +51 -30
  287. package/dist/retry/reason.js +1 -1
  288. package/dist/retry/replay.js +10 -6
  289. package/dist/retry/tracker.js +50 -12
  290. package/dist/signal/api/SignalDeviceSyncApi.js +51 -31
  291. package/dist/signal/api/SignalDigestSyncApi.js +21 -15
  292. package/dist/signal/api/SignalIdentitySyncApi.js +29 -14
  293. package/dist/signal/api/SignalMissingPreKeysSyncApi.js +17 -6
  294. package/dist/signal/api/SignalRotateKeyApi.js +4 -2
  295. package/dist/signal/api/SignalSessionSyncApi.js +16 -7
  296. package/dist/signal/api/result-map.js +13 -0
  297. package/dist/signal/constants.js +1 -5
  298. package/dist/signal/crypto/WaAdvSignature.js +2 -44
  299. package/dist/signal/crypto/constants.js +1 -5
  300. package/dist/signal/{store/sqlite.js → encoding.js} +41 -25
  301. package/dist/signal/group/SenderKeyChain.js +2 -2
  302. package/dist/signal/group/SenderKeyCodec.js +8 -8
  303. package/dist/signal/group/SenderKeyManager.js +130 -108
  304. package/dist/signal/index.js +13 -1
  305. package/dist/signal/registration/keygen.js +7 -4
  306. package/dist/signal/registration/utils.js +3 -2
  307. package/dist/signal/session/SignalProtocol.js +158 -81
  308. package/dist/signal/session/SignalRatchet.js +19 -8
  309. package/dist/signal/session/SignalSerializer.js +5 -6
  310. package/dist/signal/session/SignalSession.js +11 -9
  311. package/dist/signal/session/resolver.js +138 -103
  312. package/dist/store/contracts/identity.store.js +2 -0
  313. package/dist/store/contracts/message-secret.store.js +2 -0
  314. package/dist/store/contracts/pre-key.store.js +2 -0
  315. package/dist/store/contracts/privacy-token.store.js +2 -0
  316. package/dist/store/contracts/session.store.js +2 -0
  317. package/dist/store/createStore.js +142 -192
  318. package/dist/store/index.js +23 -33
  319. package/dist/store/locks/appstate.lock.js +29 -0
  320. package/dist/store/locks/auth.lock.js +18 -0
  321. package/dist/store/locks/contact.lock.js +23 -0
  322. package/dist/store/locks/device-list.lock.js +23 -0
  323. package/dist/store/locks/identity.lock.js +19 -0
  324. package/dist/store/locks/message-secret.lock.js +20 -0
  325. package/dist/store/locks/message.lock.js +24 -0
  326. package/dist/store/locks/participants.lock.js +23 -0
  327. package/dist/store/locks/pre-key.lock.js +30 -0
  328. package/dist/store/locks/privacy-token.lock.js +21 -0
  329. package/dist/store/locks/retry.lock.js +32 -0
  330. package/dist/store/locks/sender-key.lock.js +55 -0
  331. package/dist/store/locks/session.lock.js +22 -0
  332. package/dist/store/locks/signal.lock.js +42 -0
  333. package/dist/store/locks/thread.lock.js +24 -0
  334. package/dist/store/noop.store.js +22 -2
  335. package/dist/store/providers/memory/appstate.store.js +22 -24
  336. package/dist/store/providers/memory/device-list.store.js +13 -5
  337. package/dist/store/providers/memory/identity.store.js +35 -0
  338. package/dist/store/providers/memory/message-secret.store.js +85 -0
  339. package/dist/store/providers/memory/participants.store.js +3 -0
  340. package/dist/store/providers/memory/pre-key.store.js +101 -0
  341. package/dist/store/providers/memory/privacy-token.store.js +47 -0
  342. package/dist/store/providers/memory/retry.store.js +98 -9
  343. package/dist/store/providers/memory/sender-key.store.js +6 -1
  344. package/dist/store/providers/memory/session.store.js +49 -0
  345. package/dist/store/providers/memory/signal.store.js +1 -147
  346. package/dist/transport/WaComms.js +7 -4
  347. package/dist/transport/WaWebSocket.js +9 -7
  348. package/dist/transport/binary/constants.js +1 -31
  349. package/dist/transport/binary/decoder.js +4 -4
  350. package/dist/transport/binary/encoder.js +8 -15
  351. package/dist/transport/binary/index.js +0 -4
  352. package/dist/transport/index.js +17 -1
  353. package/dist/transport/keepalive/WaKeepAlive.js +17 -8
  354. package/dist/transport/node/WaMobileTcpSocket.js +118 -0
  355. package/dist/transport/node/WaNodeOrchestrator.js +36 -21
  356. package/dist/transport/node/builders/abprops.js +23 -0
  357. package/dist/transport/node/builders/business.js +137 -0
  358. package/dist/transport/node/builders/device.js +14 -0
  359. package/dist/transport/node/builders/email.js +72 -0
  360. package/dist/transport/node/builders/global.js +375 -0
  361. package/dist/transport/node/builders/message.js +64 -245
  362. package/dist/transport/node/builders/offline.js +17 -0
  363. package/dist/transport/node/builders/pairing.js +0 -26
  364. package/dist/transport/node/builders/prekeys.js +36 -39
  365. package/dist/transport/node/builders/presence.js +16 -0
  366. package/dist/transport/node/builders/privacy-token.js +42 -0
  367. package/dist/transport/node/builders/privacy.js +55 -0
  368. package/dist/transport/node/builders/profile.js +78 -0
  369. package/dist/transport/node/builders/retry.js +10 -22
  370. package/dist/transport/node/builders/usync.js +6 -2
  371. package/dist/transport/node/helpers.js +46 -1
  372. package/dist/transport/node/mex/argo-decoder.js +189 -0
  373. package/dist/transport/node/mex/client.js +86 -0
  374. package/dist/transport/node/mex/persist-ids.js +13 -0
  375. package/dist/transport/node/usync.js +2 -32
  376. package/dist/transport/node/xml.js +35 -14
  377. package/dist/transport/noise/WaClientPayload.js +26 -21
  378. package/dist/transport/noise/WaFrameCodec.js +1 -1
  379. package/dist/transport/noise/WaMobileClientPayload.js +56 -0
  380. package/dist/transport/noise/WaNoiseCert.js +8 -26
  381. package/dist/transport/noise/WaNoiseSession.js +75 -33
  382. package/dist/transport/noise/WaNoiseSocket.js +8 -4
  383. package/dist/transport/stream/parse.js +7 -3
  384. package/dist/types/appstate/WaAppStateCrypto.d.ts +11 -8
  385. package/dist/types/appstate/WaAppStateSyncClient.d.ts +6 -2
  386. package/dist/types/appstate/encoding.d.ts +7 -0
  387. package/dist/types/appstate/index.d.ts +3 -3
  388. package/dist/types/appstate/{WaAppStateSyncResponseParser.d.ts → response-parser.d.ts} +1 -1
  389. package/dist/types/appstate/types.d.ts +1 -1
  390. package/dist/types/appstate/utils.d.ts +0 -2
  391. package/dist/types/auth/WaAuthClient.d.ts +9 -3
  392. package/dist/types/auth/credentials-flow.d.ts +20 -0
  393. package/dist/types/auth/index.d.ts +0 -2
  394. package/dist/types/auth/pairing/WaPairingFlow.d.ts +3 -2
  395. package/dist/types/auth/pairing/{WaPairingCodeCrypto.d.ts → pairing-code-crypto.d.ts} +6 -1
  396. package/dist/types/auth/types.d.ts +41 -0
  397. package/dist/types/client/WaClient.d.ts +44 -18
  398. package/dist/types/client/WaClientFactory.d.ts +22 -8
  399. package/dist/types/client/connection/WaConnectionManager.d.ts +2 -0
  400. package/dist/types/client/coordinators/WaAbPropsCoordinator.d.ts +26 -0
  401. package/dist/types/client/coordinators/WaBusinessCoordinator.d.ts +57 -0
  402. package/dist/types/client/coordinators/WaEmailCoordinator.d.ts +24 -0
  403. package/dist/types/client/coordinators/WaIncomingNodeCoordinator.d.ts +9 -2
  404. package/dist/types/client/coordinators/WaMessageDispatchCoordinator.d.ts +29 -2
  405. package/dist/types/client/coordinators/WaOfflineResumeCoordinator.d.ts +31 -0
  406. package/dist/types/client/coordinators/WaPassiveTasksCoordinator.d.ts +16 -1
  407. package/dist/types/client/coordinators/WaPrivacyCoordinator.d.ts +26 -0
  408. package/dist/types/client/coordinators/WaProfileCoordinator.d.ts +38 -0
  409. package/dist/types/client/coordinators/WaRetryCoordinator.d.ts +12 -0
  410. package/dist/types/client/coordinators/WaStreamControlCoordinator.d.ts +3 -2
  411. package/dist/types/client/coordinators/WaTrustedContactTokenCoordinator.d.ts +55 -0
  412. package/dist/types/client/dirty.d.ts +3 -1
  413. package/dist/types/client/events/abprops.d.ts +14 -0
  414. package/dist/types/client/events/devices.d.ts +20 -0
  415. package/dist/types/client/events/identity.d.ts +9 -0
  416. package/dist/types/client/events/privacy-token.d.ts +7 -0
  417. package/dist/types/client/events/registration.d.ts +17 -0
  418. package/dist/types/client/history-sync.d.ts +9 -6
  419. package/dist/types/client/incoming.d.ts +9 -2
  420. package/dist/types/client/index.d.ts +1 -1
  421. package/dist/types/client/mailbox.d.ts +5 -5
  422. package/dist/types/client/media.d.ts +31 -0
  423. package/dist/types/client/messages.d.ts +3 -2
  424. package/dist/types/client/persistence/WriteBehindPersistence.d.ts +34 -0
  425. package/dist/types/client/tokens/cs-token.d.ts +10 -0
  426. package/dist/types/client/tokens/tc-token.d.ts +5 -0
  427. package/dist/types/client/types.d.ts +151 -4
  428. package/dist/types/crypto/core/index.d.ts +3 -2
  429. package/dist/types/crypto/core/nonce.d.ts +2 -0
  430. package/dist/types/crypto/core/primitives.d.ts +1 -2
  431. package/dist/types/crypto/core/random.d.ts +2 -1
  432. package/dist/types/crypto/core/xeddsa.d.ts +2 -0
  433. package/dist/types/crypto/curves/constants.d.ts +1 -0
  434. package/dist/types/crypto/index.d.ts +2 -0
  435. package/dist/types/crypto/math/constants.d.ts +4 -2
  436. package/dist/types/crypto/math/fe.d.ts +30 -0
  437. package/dist/types/crypto/math/mod.d.ts +0 -2
  438. package/dist/types/crypto/math/types.d.ts +11 -4
  439. package/dist/types/index.d.ts +6 -3
  440. package/dist/types/infra/log/ConsoleLogger.d.ts +1 -1
  441. package/dist/types/infra/log/PinoLogger.d.ts +1 -1
  442. package/dist/types/infra/perf/BackgroundQueue.d.ts +58 -0
  443. package/dist/types/infra/perf/PromiseDedup.d.ts +4 -0
  444. package/dist/types/infra/perf/SharedExclusiveGate.d.ts +17 -0
  445. package/dist/types/infra/perf/StoreLock.d.ts +11 -0
  446. package/dist/types/media/WaMediaCrypto.d.ts +16 -6
  447. package/dist/types/media/WaMediaTransferClient.d.ts +6 -23
  448. package/dist/types/media/constants.d.ts +3 -1
  449. package/dist/types/media/index.d.ts +2 -1
  450. package/dist/types/media/processor.d.ts +28 -0
  451. package/dist/types/media/types.d.ts +19 -5
  452. package/dist/types/message/addon-crypto.d.ts +34 -3
  453. package/dist/types/message/content.d.ts +11 -1
  454. package/dist/types/message/icdc.d.ts +13 -0
  455. package/dist/types/message/reporting-token.d.ts +0 -1
  456. package/dist/types/message/types.d.ts +42 -11
  457. package/dist/types/protocol/abprops.d.ts +142 -0
  458. package/dist/types/protocol/appstate.d.ts +0 -11
  459. package/dist/types/protocol/browser.d.ts +1 -0
  460. package/dist/types/protocol/constants.d.ts +12 -4
  461. package/dist/types/protocol/defaults.d.ts +6 -0
  462. package/dist/types/protocol/email.d.ts +32 -0
  463. package/dist/types/protocol/index.d.ts +1 -2
  464. package/dist/types/protocol/jid.d.ts +20 -2
  465. package/dist/types/protocol/message.d.ts +60 -0
  466. package/dist/types/protocol/nodes.d.ts +6 -0
  467. package/dist/types/protocol/notification.d.ts +8 -0
  468. package/dist/types/protocol/privacy-token.d.ts +17 -0
  469. package/dist/types/protocol/privacy.d.ts +75 -0
  470. package/dist/types/protocol/stream.d.ts +31 -0
  471. package/dist/types/retry/codec.d.ts +3 -0
  472. package/dist/types/retry/index.d.ts +3 -3
  473. package/dist/types/retry/parse.d.ts +5 -2
  474. package/dist/types/retry/reason.d.ts +1 -1
  475. package/dist/types/retry/tracker.d.ts +1 -0
  476. package/dist/types/retry/types.d.ts +6 -1
  477. package/dist/types/signal/api/SignalDeviceSyncApi.d.ts +2 -1
  478. package/dist/types/signal/api/SignalDigestSyncApi.d.ts +9 -0
  479. package/dist/types/signal/api/SignalIdentitySyncApi.d.ts +5 -3
  480. package/dist/types/signal/api/SignalRotateKeyApi.d.ts +4 -5
  481. package/dist/types/signal/api/SignalSessionSyncApi.d.ts +8 -6
  482. package/dist/types/signal/api/result-map.d.ts +1 -0
  483. package/dist/types/signal/constants.d.ts +0 -3
  484. package/dist/types/signal/crypto/WaAdvSignature.d.ts +0 -2
  485. package/dist/types/signal/crypto/constants.d.ts +0 -1
  486. package/dist/types/signal/{store/sqlite.d.ts → encoding.d.ts} +9 -3
  487. package/dist/types/signal/group/SenderKeyChain.d.ts +1 -1
  488. package/dist/types/signal/group/SenderKeyManager.d.ts +17 -7
  489. package/dist/types/signal/index.d.ts +2 -0
  490. package/dist/types/signal/registration/utils.d.ts +2 -1
  491. package/dist/types/signal/session/SignalProtocol.d.ts +21 -6
  492. package/dist/types/signal/session/SignalSerializer.d.ts +2 -1
  493. package/dist/types/signal/session/resolver.d.ts +11 -4
  494. package/dist/types/signal/types.d.ts +16 -4
  495. package/dist/types/store/contracts/appstate.store.d.ts +1 -1
  496. package/dist/types/store/contracts/identity.store.d.ts +11 -0
  497. package/dist/types/store/contracts/message-secret.store.d.ts +16 -0
  498. package/dist/types/store/contracts/pre-key.store.d.ts +13 -0
  499. package/dist/types/store/contracts/privacy-token.store.d.ts +16 -0
  500. package/dist/types/store/contracts/retry.store.d.ts +7 -0
  501. package/dist/types/store/contracts/session.store.d.ts +14 -0
  502. package/dist/types/store/contracts/signal.store.d.ts +1 -27
  503. package/dist/types/store/createStore.d.ts +1 -1
  504. package/dist/types/store/index.d.ts +12 -12
  505. package/dist/types/store/locks/appstate.lock.d.ts +3 -0
  506. package/dist/types/store/locks/auth.lock.d.ts +3 -0
  507. package/dist/types/store/locks/contact.lock.d.ts +3 -0
  508. package/dist/types/store/locks/device-list.lock.d.ts +2 -0
  509. package/dist/types/store/locks/identity.lock.d.ts +3 -0
  510. package/dist/types/store/locks/message-secret.lock.d.ts +3 -0
  511. package/dist/types/store/locks/message.lock.d.ts +3 -0
  512. package/dist/types/store/locks/participants.lock.d.ts +2 -0
  513. package/dist/types/store/locks/pre-key.lock.d.ts +3 -0
  514. package/dist/types/store/locks/privacy-token.lock.d.ts +2 -0
  515. package/dist/types/store/locks/retry.lock.d.ts +2 -0
  516. package/dist/types/store/locks/sender-key.lock.d.ts +3 -0
  517. package/dist/types/store/locks/session.lock.d.ts +3 -0
  518. package/dist/types/store/locks/signal.lock.d.ts +3 -0
  519. package/dist/types/store/locks/thread.lock.d.ts +3 -0
  520. package/dist/types/store/noop.store.d.ts +4 -0
  521. package/dist/types/store/providers/memory/appstate.store.d.ts +1 -1
  522. package/dist/types/store/providers/memory/identity.store.d.ts +18 -0
  523. package/dist/types/store/providers/memory/message-secret.store.d.ts +21 -0
  524. package/dist/types/store/providers/memory/pre-key.store.d.ts +23 -0
  525. package/dist/types/store/providers/memory/privacy-token.store.d.ts +13 -0
  526. package/dist/types/store/providers/memory/retry.store.d.ts +15 -1
  527. package/dist/types/store/providers/memory/session.store.d.ts +21 -0
  528. package/dist/types/store/providers/memory/signal.store.d.ts +2 -43
  529. package/dist/types/store/providers/memory/thread.store.d.ts +1 -1
  530. package/dist/types/store/types.d.ts +69 -61
  531. package/dist/types/transport/WaWebSocket.d.ts +1 -1
  532. package/dist/types/transport/binary/constants.d.ts +0 -30
  533. package/dist/types/transport/binary/index.d.ts +0 -1
  534. package/dist/types/transport/index.d.ts +8 -1
  535. package/dist/types/transport/keepalive/WaKeepAlive.d.ts +4 -1
  536. package/dist/types/transport/node/WaMobileTcpSocket.d.ts +18 -0
  537. package/dist/types/transport/node/WaNodeOrchestrator.d.ts +9 -6
  538. package/dist/types/transport/node/builders/abprops.d.ts +5 -0
  539. package/dist/types/transport/node/builders/business.d.ts +29 -0
  540. package/dist/types/transport/node/builders/device.d.ts +2 -0
  541. package/dist/types/transport/node/builders/email.d.ts +11 -0
  542. package/dist/types/transport/node/builders/global.d.ts +102 -0
  543. package/dist/types/transport/node/builders/message.d.ts +8 -7
  544. package/dist/types/transport/node/builders/offline.d.ts +2 -0
  545. package/dist/types/transport/node/builders/pairing.d.ts +0 -2
  546. package/dist/types/transport/node/builders/prekeys.d.ts +4 -3
  547. package/dist/types/transport/node/builders/presence.d.ts +6 -0
  548. package/dist/types/transport/node/builders/privacy-token.d.ts +9 -0
  549. package/dist/types/transport/node/builders/privacy.d.ts +7 -0
  550. package/dist/types/transport/node/builders/profile.d.ts +8 -0
  551. package/dist/types/transport/node/builders/retry.d.ts +0 -1
  552. package/dist/types/transport/node/helpers.d.ts +8 -0
  553. package/dist/types/transport/node/mex/argo-decoder.d.ts +11 -0
  554. package/dist/types/transport/node/mex/client.d.ts +18 -0
  555. package/dist/types/transport/node/mex/persist-ids.d.ts +14 -0
  556. package/dist/types/transport/noise/WaMobileClientPayload.d.ts +29 -0
  557. package/dist/types/transport/noise/WaNoiseCert.d.ts +7 -1
  558. package/dist/types/transport/noise/WaNoiseSession.d.ts +4 -2
  559. package/dist/types/transport/noise/WaNoiseSocket.d.ts +4 -2
  560. package/dist/types/transport/types.d.ts +8 -0
  561. package/dist/types/util/bytes.d.ts +1 -1
  562. package/dist/types/util/index.d.ts +5 -0
  563. package/dist/types/util/primitives.d.ts +0 -1
  564. package/dist/util/bytes.js +22 -18
  565. package/dist/util/index.js +23 -0
  566. package/dist/util/primitives.js +2 -2
  567. package/package.json +34 -10
  568. package/proto/index.js +1 -1
  569. package/dist/auth/flow/WaAuthCredentialsFlow.js +0 -130
  570. package/dist/auth/pairing/constants.js +0 -5
  571. package/dist/client/connection/WaKeyShareCoordinator.js +0 -63
  572. package/dist/crypto/core/constants.js +0 -4
  573. package/dist/esm/auth/flow/WaAuthCredentialsFlow.js +0 -125
  574. package/dist/esm/auth/pairing/constants.js +0 -2
  575. package/dist/esm/client/connection/WaKeyShareCoordinator.js +0 -59
  576. package/dist/esm/crypto/core/constants.js +0 -1
  577. package/dist/esm/retry/outbound.js +0 -82
  578. package/dist/esm/store/providers/sqlite/BaseSqliteStore.js +0 -37
  579. package/dist/esm/store/providers/sqlite/appstate.store.js +0 -250
  580. package/dist/esm/store/providers/sqlite/auth.store.js +0 -176
  581. package/dist/esm/store/providers/sqlite/connection.js +0 -245
  582. package/dist/esm/store/providers/sqlite/contact.store.js +0 -74
  583. package/dist/esm/store/providers/sqlite/device-list.store.js +0 -127
  584. package/dist/esm/store/providers/sqlite/message.store.js +0 -132
  585. package/dist/esm/store/providers/sqlite/migrations.js +0 -347
  586. package/dist/esm/store/providers/sqlite/participants.store.js +0 -77
  587. package/dist/esm/store/providers/sqlite/retry.store.js +0 -141
  588. package/dist/esm/store/providers/sqlite/sender-key.store.js +0 -198
  589. package/dist/esm/store/providers/sqlite/signal.store.js +0 -435
  590. package/dist/esm/store/providers/sqlite/table-names.js +0 -107
  591. package/dist/esm/store/providers/sqlite/thread.store.js +0 -85
  592. package/dist/esm/transport/node/builders/index.js +0 -8
  593. package/dist/retry/outbound.js +0 -87
  594. package/dist/store/providers/sqlite/BaseSqliteStore.js +0 -41
  595. package/dist/store/providers/sqlite/appstate.store.js +0 -254
  596. package/dist/store/providers/sqlite/auth.store.js +0 -180
  597. package/dist/store/providers/sqlite/connection.js +0 -281
  598. package/dist/store/providers/sqlite/contact.store.js +0 -78
  599. package/dist/store/providers/sqlite/device-list.store.js +0 -131
  600. package/dist/store/providers/sqlite/message.store.js +0 -136
  601. package/dist/store/providers/sqlite/migrations.js +0 -350
  602. package/dist/store/providers/sqlite/participants.store.js +0 -81
  603. package/dist/store/providers/sqlite/retry.store.js +0 -145
  604. package/dist/store/providers/sqlite/sender-key.store.js +0 -202
  605. package/dist/store/providers/sqlite/signal.store.js +0 -439
  606. package/dist/store/providers/sqlite/table-names.js +0 -113
  607. package/dist/store/providers/sqlite/thread.store.js +0 -89
  608. package/dist/transport/node/builders/index.js +0 -42
  609. package/dist/types/appstate/store/sqlite.d.ts +0 -7
  610. package/dist/types/auth/flow/WaAuthCredentialsFlow.d.ts +0 -14
  611. package/dist/types/auth/pairing/constants.d.ts +0 -2
  612. package/dist/types/client/connection/WaKeyShareCoordinator.d.ts +0 -14
  613. package/dist/types/crypto/core/constants.d.ts +0 -1
  614. package/dist/types/retry/outbound.d.ts +0 -4
  615. package/dist/types/store/providers/sqlite/BaseSqliteStore.d.ts +0 -12
  616. package/dist/types/store/providers/sqlite/appstate.store.d.ts +0 -17
  617. package/dist/types/store/providers/sqlite/auth.store.d.ts +0 -10
  618. package/dist/types/store/providers/sqlite/connection.d.ts +0 -10
  619. package/dist/types/store/providers/sqlite/contact.store.d.ts +0 -12
  620. package/dist/types/store/providers/sqlite/device-list.store.d.ts +0 -15
  621. package/dist/types/store/providers/sqlite/message.store.d.ts +0 -13
  622. package/dist/types/store/providers/sqlite/migrations.d.ts +0 -3
  623. package/dist/types/store/providers/sqlite/participants.store.d.ts +0 -12
  624. package/dist/types/store/providers/sqlite/retry.store.d.ts +0 -15
  625. package/dist/types/store/providers/sqlite/sender-key.store.d.ts +0 -24
  626. package/dist/types/store/providers/sqlite/signal.store.d.ts +0 -53
  627. package/dist/types/store/providers/sqlite/table-names.d.ts +0 -5
  628. package/dist/types/store/providers/sqlite/thread.store.d.ts +0 -13
  629. package/dist/types/transport/node/builders/index.d.ts +0 -8
  630. /package/dist/appstate/{WaAppStateSyncResponseParser.js → response-parser.js} +0 -0
@@ -0,0 +1,110 @@
1
+ import { buildOfflineBatchNode } from '../../transport/node/builders/offline.js';
2
+ import { toError } from '../../util/primitives.js';
3
+ const WA_OFFLINE_RESUME = Object.freeze({
4
+ BATCH_SIZE: 200,
5
+ STANZA_TIMEOUT_MS: 60000
6
+ });
7
+ const WA_OFFLINE_RESUME_STATE = Object.freeze({
8
+ INIT: 'init',
9
+ RESUMING: 'resuming',
10
+ COMPLETE: 'complete'
11
+ });
12
+ export class WaOfflineResumeCoordinator {
13
+ constructor(options) {
14
+ this.logger = options.logger;
15
+ this.runtime = options.runtime;
16
+ this.state = WA_OFFLINE_RESUME_STATE.INIT;
17
+ this.totalStanzas = 0;
18
+ this.pendingStanzas = 0;
19
+ this.stanzaTimeout = null;
20
+ }
21
+ get isComplete() {
22
+ return this.state === WA_OFFLINE_RESUME_STATE.COMPLETE;
23
+ }
24
+ get isResuming() {
25
+ return this.state === WA_OFFLINE_RESUME_STATE.RESUMING;
26
+ }
27
+ handleOfflinePreview(stanzaCount) {
28
+ this.clearTimers();
29
+ this.state = WA_OFFLINE_RESUME_STATE.RESUMING;
30
+ this.totalStanzas = stanzaCount;
31
+ this.pendingStanzas = stanzaCount;
32
+ this.logger.info('offline resume started', {
33
+ totalStanzas: stanzaCount
34
+ });
35
+ this.runtime.emitOfflineResume({
36
+ status: 'resuming',
37
+ totalStanzas: stanzaCount,
38
+ remainingStanzas: stanzaCount,
39
+ forced: false
40
+ });
41
+ void this.sendOfflineBatch();
42
+ this.resetStanzaTimeout();
43
+ }
44
+ handleOfflineComplete(serverStanzaCount) {
45
+ if (this.state !== WA_OFFLINE_RESUME_STATE.RESUMING) {
46
+ return;
47
+ }
48
+ this.completeResume(false, serverStanzaCount);
49
+ }
50
+ trackOfflineStanza() {
51
+ if (this.state !== WA_OFFLINE_RESUME_STATE.RESUMING) {
52
+ return;
53
+ }
54
+ this.pendingStanzas = Math.max(0, this.pendingStanzas - 1);
55
+ this.resetStanzaTimeout();
56
+ }
57
+ reset() {
58
+ this.clearTimers();
59
+ this.state = WA_OFFLINE_RESUME_STATE.INIT;
60
+ this.totalStanzas = 0;
61
+ this.pendingStanzas = 0;
62
+ }
63
+ completeResume(forced, serverStanzaCount) {
64
+ this.clearTimers();
65
+ this.state = WA_OFFLINE_RESUME_STATE.COMPLETE;
66
+ this.logger.info('offline resume complete', {
67
+ totalStanzas: this.totalStanzas,
68
+ remainingStanzas: this.pendingStanzas,
69
+ serverStanzaCount,
70
+ forced
71
+ });
72
+ this.runtime.emitOfflineResume({
73
+ status: 'complete',
74
+ totalStanzas: this.totalStanzas,
75
+ remainingStanzas: this.pendingStanzas,
76
+ forced
77
+ });
78
+ }
79
+ async sendOfflineBatch() {
80
+ try {
81
+ await this.runtime.sendNode(buildOfflineBatchNode(WA_OFFLINE_RESUME.BATCH_SIZE));
82
+ }
83
+ catch (err) {
84
+ this.logger.warn('offline batch request failed', {
85
+ message: toError(err).message
86
+ });
87
+ }
88
+ }
89
+ resetStanzaTimeout() {
90
+ if (this.stanzaTimeout !== null) {
91
+ clearTimeout(this.stanzaTimeout);
92
+ }
93
+ this.stanzaTimeout = setTimeout(() => {
94
+ this.stanzaTimeout = null;
95
+ if (this.state === WA_OFFLINE_RESUME_STATE.RESUMING) {
96
+ this.logger.warn('offline resume forced complete due to stanza timeout', {
97
+ totalStanzas: this.totalStanzas,
98
+ remainingStanzas: this.pendingStanzas
99
+ });
100
+ this.completeResume(true);
101
+ }
102
+ }, WA_OFFLINE_RESUME.STANZA_TIMEOUT_MS);
103
+ }
104
+ clearTimers() {
105
+ if (this.stanzaTimeout !== null) {
106
+ clearTimeout(this.stanzaTimeout);
107
+ this.stanzaTimeout = null;
108
+ }
109
+ }
110
+ }
@@ -7,6 +7,7 @@ export class WaPassiveTasksCoordinator {
7
7
  constructor(options) {
8
8
  this.logger = options.logger;
9
9
  this.signalStore = options.signalStore;
10
+ this.preKeyStore = options.preKeyStore;
10
11
  this.signalDigestSync = options.signalDigestSync;
11
12
  this.signalRotateKey = options.signalRotateKey;
12
13
  this.signedPreKeyRotationIntervalMs =
@@ -14,6 +15,8 @@ export class WaPassiveTasksCoordinator {
14
15
  this.signedPreKeyServerErrorBackoffMs =
15
16
  options.signedPreKeyServerErrorBackoffMs ?? SIGNAL_SIGNED_PREKEY_SERVER_ERROR_BACKOFF_MS;
16
17
  this.runtime = options.runtime;
18
+ this.mobilePrimary = options.mobilePrimary ?? false;
19
+ this.appStateSync = options.appStateSync;
17
20
  this.passiveTasksPromise = null;
18
21
  }
19
22
  startPassiveTasksAfterConnect() {
@@ -31,6 +34,16 @@ export class WaPassiveTasksCoordinator {
31
34
  this.passiveTasksPromise = null;
32
35
  });
33
36
  }
37
+ async handlePreKeyLowNotification() {
38
+ await Promise.all([
39
+ this.preKeyStore.setServerHasPreKeys(false),
40
+ this.runtime.persistServerHasPreKeys(false)
41
+ ]);
42
+ await this.uploadPreKeysIfMissing(false);
43
+ }
44
+ async handleDigestNotification() {
45
+ await this.validateDigestAndRecoverPreKeys();
46
+ }
34
47
  resetInFlightState() {
35
48
  if (!this.passiveTasksPromise) {
36
49
  return;
@@ -44,14 +57,36 @@ export class WaPassiveTasksCoordinator {
44
57
  this.logger.trace('passive connect tasks skipped: session is not registered');
45
58
  return;
46
59
  }
47
- await this.uploadPreKeysIfMissing();
48
- await this.validateDigestAndRecoverPreKeys();
49
- await this.rotateSignedPreKeyIfDue();
60
+ this.runtime.syncAbProps();
61
+ if (this.mobilePrimary && this.appStateSync) {
62
+ await this.appStateSync.ensureInitialSyncKey().catch((error) => {
63
+ this.logger.warn('app-state initial key generation failed', {
64
+ message: toError(error).message
65
+ });
66
+ });
67
+ }
68
+ await this.runtime.sendPresenceAvailable().catch((error) => {
69
+ this.logger.warn('presence available send failed', {
70
+ message: toError(error).message
71
+ });
72
+ });
73
+ const [registrationInfo, signedPreKey, serverHasPreKeys, signedPreKeyRotationTs] = await Promise.all([
74
+ this.signalStore.getRegistrationInfo(),
75
+ this.signalStore.getSignedPreKey(),
76
+ this.preKeyStore.getServerHasPreKeys(),
77
+ this.signalStore.getSignedPreKeyRotationTs()
78
+ ]);
79
+ const prefetchedLocalKeyBundle = registrationInfo && signedPreKey ? { registrationInfo, signedPreKey } : null;
80
+ await this.uploadPreKeysIfMissing(serverHasPreKeys, prefetchedLocalKeyBundle);
81
+ await this.validateDigestAndRecoverPreKeys(prefetchedLocalKeyBundle);
82
+ await this.rotateSignedPreKeyIfDue(signedPreKeyRotationTs);
50
83
  await this.flushDanglingReceipts();
51
84
  }
52
- async validateDigestAndRecoverPreKeys() {
85
+ async validateDigestAndRecoverPreKeys(prefetchedLocalKeyBundle) {
53
86
  try {
54
- const validation = await this.signalDigestSync.validateLocalKeyBundle();
87
+ const validation = prefetchedLocalKeyBundle
88
+ ? await this.signalDigestSync.validateLocalKeyBundle(prefetchedLocalKeyBundle)
89
+ : await this.signalDigestSync.validateLocalKeyBundle();
55
90
  if (validation.valid) {
56
91
  this.logger.debug('signal digest validated', {
57
92
  preKeyCount: validation.preKeyCount
@@ -67,10 +102,10 @@ export class WaPassiveTasksCoordinator {
67
102
  return;
68
103
  }
69
104
  await Promise.all([
70
- this.signalStore.setServerHasPreKeys(false),
105
+ this.preKeyStore.setServerHasPreKeys(false),
71
106
  this.runtime.persistServerHasPreKeys(false)
72
107
  ]);
73
- await this.uploadPreKeysIfMissing();
108
+ await this.uploadPreKeysIfMissing(false, prefetchedLocalKeyBundle);
74
109
  }
75
110
  catch (error) {
76
111
  this.logger.warn('signal digest validation failed with exception', {
@@ -78,21 +113,19 @@ export class WaPassiveTasksCoordinator {
78
113
  });
79
114
  }
80
115
  }
81
- async uploadPreKeysIfMissing() {
82
- const serverHasPreKeys = await this.signalStore.getServerHasPreKeys();
116
+ async uploadPreKeysIfMissing(serverHasPreKeysHint, prefetchedLocalKeyBundle) {
117
+ const serverHasPreKeys = serverHasPreKeysHint ?? (await this.preKeyStore.getServerHasPreKeys());
83
118
  if (serverHasPreKeys) {
84
119
  this.logger.trace('prekey upload skipped: server already has prekeys');
85
120
  return;
86
121
  }
87
- const [registrationInfo, signedPreKey] = await Promise.all([
88
- this.signalStore.getRegistrationInfo(),
89
- this.signalStore.getSignedPreKey()
90
- ]);
91
- if (!registrationInfo || !signedPreKey) {
122
+ const resolvedLocalKeyBundle = prefetchedLocalKeyBundle ?? (await this.resolveLocalKeyBundleFromStore());
123
+ if (!resolvedLocalKeyBundle) {
92
124
  this.logger.warn('prekey upload skipped: registration info is missing');
93
125
  return;
94
126
  }
95
- const preKeys = await this.signalStore.getOrGenPreKeys(SIGNAL_UPLOAD_PREKEYS_COUNT, generatePreKeyPair);
127
+ const { registrationInfo, signedPreKey } = resolvedLocalKeyBundle;
128
+ const preKeys = await this.preKeyStore.getOrGenPreKeys(SIGNAL_UPLOAD_PREKEYS_COUNT, generatePreKeyPair);
96
129
  if (preKeys.length === 0) {
97
130
  throw new Error('no prekey available for upload');
98
131
  }
@@ -101,11 +134,12 @@ export class WaPassiveTasksCoordinator {
101
134
  const response = await this.runtime.queryWithContext('prekeys.upload', uploadNode, WA_DEFAULTS.IQ_TIMEOUT_MS, {
102
135
  count: preKeys.length,
103
136
  lastPreKeyId
104
- });
137
+ }, this.mobilePrimary ? { useSystemId: true } : undefined);
105
138
  if (response.attrs.type === 'result') {
106
- await this.signalStore.markKeyAsUploaded(lastPreKeyId);
139
+ // Mark uploaded key first so the serverHasPreKeys flag never commits ahead of local key progress.
140
+ await this.preKeyStore.markKeyAsUploaded(lastPreKeyId);
107
141
  await Promise.all([
108
- this.signalStore.setServerHasPreKeys(true),
142
+ this.preKeyStore.setServerHasPreKeys(true),
109
143
  this.runtime.persistServerHasPreKeys(true)
110
144
  ]);
111
145
  this.logger.info('uploaded prekeys to server', {
@@ -121,10 +155,12 @@ export class WaPassiveTasksCoordinator {
121
155
  errorText: failure.errorText
122
156
  });
123
157
  }
124
- async rotateSignedPreKeyIfDue() {
158
+ async rotateSignedPreKeyIfDue(signedPreKeyRotationTsHint) {
125
159
  try {
126
160
  const nowMs = Date.now();
127
- const lastRotationTs = await this.signalStore.getSignedPreKeyRotationTs();
161
+ const lastRotationTs = signedPreKeyRotationTsHint === undefined
162
+ ? await this.signalStore.getSignedPreKeyRotationTs()
163
+ : signedPreKeyRotationTsHint;
128
164
  if (lastRotationTs === null) {
129
165
  await this.signalStore.setSignedPreKeyRotationTs(nowMs);
130
166
  this.logger.trace('signal rotate key skipped on first run');
@@ -150,6 +186,16 @@ export class WaPassiveTasksCoordinator {
150
186
  });
151
187
  }
152
188
  }
189
+ async resolveLocalKeyBundleFromStore() {
190
+ const [registrationInfo, signedPreKey] = await Promise.all([
191
+ this.signalStore.getRegistrationInfo(),
192
+ this.signalStore.getSignedPreKey()
193
+ ]);
194
+ if (!registrationInfo || !signedPreKey) {
195
+ return null;
196
+ }
197
+ return { registrationInfo, signedPreKey };
198
+ }
153
199
  resolveRotationTimestamp(nowMs, errorCode) {
154
200
  if (errorCode !== undefined && errorCode >= 500) {
155
201
  const retryInMs = Math.min(this.signedPreKeyServerErrorBackoffMs, this.signedPreKeyRotationIntervalMs);
@@ -167,29 +213,44 @@ export class WaPassiveTasksCoordinator {
167
213
  return;
168
214
  }
169
215
  this.logger.info('flushing dangling receipts', { count: pending.length });
170
- for (let index = 0; index < pending.length; index += 1) {
171
- const node = pending[index];
172
- try {
173
- await this.runtime.sendNodeDirect(node);
216
+ let cursor = 0;
217
+ while (cursor < pending.length) {
218
+ const batchEnd = Math.min(cursor + 4, pending.length);
219
+ const promises = [];
220
+ for (let i = cursor; i < batchEnd; i += 1) {
221
+ promises.push(this.runtime.sendNodeDirect(pending[i]));
174
222
  }
175
- catch (error) {
176
- const normalized = toError(error);
223
+ const results = await Promise.allSettled(promises);
224
+ let transientCount = 0;
225
+ for (let i = 0; i < results.length; i += 1) {
226
+ const result = results[i];
227
+ if (result.status === 'fulfilled') {
228
+ continue;
229
+ }
230
+ const node = pending[cursor + i];
231
+ const normalized = toError(result.reason);
177
232
  if (this.runtime.shouldQueueDanglingReceipt(node, normalized)) {
178
- for (let restoreIndex = index; restoreIndex < pending.length; restoreIndex += 1) {
179
- this.runtime.requeueDanglingReceipt(pending[restoreIndex]);
180
- }
181
- this.logger.warn('stopped dangling receipt flush due transient send error', {
182
- remaining: pending.length - index,
233
+ this.runtime.requeueDanglingReceipt(node);
234
+ transientCount += 1;
235
+ }
236
+ else {
237
+ this.logger.warn('dropping dangling receipt due non-retryable send error', {
238
+ id: node.attrs.id,
239
+ to: node.attrs.to,
183
240
  message: normalized.message
184
241
  });
185
- return;
186
242
  }
187
- this.logger.warn('dropping dangling receipt due non-retryable send error', {
188
- id: node.attrs.id,
189
- to: node.attrs.to,
190
- message: normalized.message
243
+ }
244
+ if (transientCount > 0) {
245
+ for (let i = batchEnd; i < pending.length; i += 1) {
246
+ this.runtime.requeueDanglingReceipt(pending[i]);
247
+ }
248
+ this.logger.warn('stopped dangling receipt flush due transient send error', {
249
+ remaining: transientCount + (pending.length - batchEnd)
191
250
  });
251
+ return;
192
252
  }
253
+ cursor = batchEnd;
193
254
  }
194
255
  this.logger.info('dangling receipts flushed');
195
256
  }
@@ -0,0 +1,131 @@
1
+ import { WA_PRIVACY_CATEGORY_TO_SETTING, WA_PRIVACY_SETTING_TO_CATEGORY, WA_PRIVACY_TAGS, WA_PRIVACY_VALUES } from '../../protocol/privacy.js';
2
+ import { buildBlocklistChangeIq, buildGetBlocklistIq, buildGetPrivacyDisallowedListIq, buildGetPrivacySettingsIq, buildSetPrivacyCategoryIq } from '../../transport/node/builders/privacy.js';
3
+ import { findNodeChild, getNodeChildren, getNodeChildrenByTag } from '../../transport/node/helpers.js';
4
+ import { assertIqResult } from '../../transport/node/query.js';
5
+ const IGNORED_SERVER_CATEGORIES = new Set([
6
+ 'pix',
7
+ 'linked_profiles',
8
+ 'stickers',
9
+ 'dependentaccountmessages',
10
+ 'cover_photo',
11
+ 'dependent_account_calling',
12
+ 'groupcreation'
13
+ ]);
14
+ function isValidPrivacyValue(value) {
15
+ return (value !== WA_PRIVACY_VALUES.ERROR &&
16
+ Object.values(WA_PRIVACY_VALUES).includes(value));
17
+ }
18
+ function parsePrivacySettings(result) {
19
+ const privacyNode = findNodeChild(result, 'privacy');
20
+ if (!privacyNode) {
21
+ return {};
22
+ }
23
+ const settings = {};
24
+ const categories = getNodeChildrenByTag(privacyNode, WA_PRIVACY_TAGS.CATEGORY);
25
+ for (let i = 0; i < categories.length; i += 1) {
26
+ const node = categories[i];
27
+ const name = node.attrs.name;
28
+ const value = node.attrs.value;
29
+ if (!name || !value) {
30
+ continue;
31
+ }
32
+ if (IGNORED_SERVER_CATEGORIES.has(name)) {
33
+ continue;
34
+ }
35
+ if (!isValidPrivacyValue(value)) {
36
+ continue;
37
+ }
38
+ const settingName = WA_PRIVACY_CATEGORY_TO_SETTING[name];
39
+ if (settingName) {
40
+ settings[settingName] = value;
41
+ }
42
+ }
43
+ return settings;
44
+ }
45
+ function parseDisallowedList(result) {
46
+ const privacyNode = findNodeChild(result, 'privacy');
47
+ if (!privacyNode) {
48
+ return { jids: [] };
49
+ }
50
+ const listNode = findNodeChild(privacyNode, WA_PRIVACY_TAGS.LIST);
51
+ if (!listNode) {
52
+ return { jids: [] };
53
+ }
54
+ const dhash = listNode.attrs.dhash;
55
+ const userNodes = getNodeChildrenByTag(listNode, WA_PRIVACY_TAGS.USER);
56
+ const jids = new Array(userNodes.length);
57
+ let jidsCount = 0;
58
+ for (let i = 0; i < userNodes.length; i += 1) {
59
+ const jid = userNodes[i].attrs.jid;
60
+ if (jid) {
61
+ jids[jidsCount] = jid;
62
+ jidsCount += 1;
63
+ }
64
+ }
65
+ jids.length = jidsCount;
66
+ return { jids, dhash };
67
+ }
68
+ function parseBlocklist(result) {
69
+ const listNode = findNodeChild(result, 'list');
70
+ if (!listNode) {
71
+ return { jids: [] };
72
+ }
73
+ const dhash = listNode.attrs.dhash;
74
+ const itemNodes = getNodeChildren(listNode);
75
+ const jids = new Array(itemNodes.length);
76
+ let jidsCount = 0;
77
+ for (let i = 0; i < itemNodes.length; i += 1) {
78
+ const jid = itemNodes[i].attrs.jid;
79
+ if (jid) {
80
+ jids[jidsCount] = jid;
81
+ jidsCount += 1;
82
+ }
83
+ }
84
+ jids.length = jidsCount;
85
+ return { jids, dhash };
86
+ }
87
+ export function createPrivacyCoordinator(options) {
88
+ const { queryWithContext } = options;
89
+ return {
90
+ getPrivacySettings: async () => {
91
+ const node = buildGetPrivacySettingsIq();
92
+ const result = await queryWithContext('privacy.getSettings', node);
93
+ assertIqResult(result, 'privacy.getSettings');
94
+ return parsePrivacySettings(result);
95
+ },
96
+ setPrivacySetting: async (setting, value) => {
97
+ const category = WA_PRIVACY_SETTING_TO_CATEGORY[setting];
98
+ const node = buildSetPrivacyCategoryIq(category, value);
99
+ const result = await queryWithContext('privacy.setSetting', node, undefined, {
100
+ category,
101
+ value
102
+ });
103
+ assertIqResult(result, 'privacy.setSetting');
104
+ },
105
+ getDisallowedList: async (setting) => {
106
+ const category = WA_PRIVACY_SETTING_TO_CATEGORY[setting];
107
+ const node = buildGetPrivacyDisallowedListIq(category);
108
+ const result = await queryWithContext('privacy.getDisallowedList', node, undefined, {
109
+ category
110
+ });
111
+ assertIqResult(result, 'privacy.getDisallowedList');
112
+ return parseDisallowedList(result);
113
+ },
114
+ getBlocklist: async () => {
115
+ const node = buildGetBlocklistIq();
116
+ const result = await queryWithContext('privacy.getBlocklist', node);
117
+ assertIqResult(result, 'privacy.getBlocklist');
118
+ return parseBlocklist(result);
119
+ },
120
+ blockUser: async (jid) => {
121
+ const node = buildBlocklistChangeIq(jid, 'block');
122
+ const result = await queryWithContext('privacy.blockUser', node, undefined, { jid });
123
+ assertIqResult(result, 'privacy.blockUser');
124
+ },
125
+ unblockUser: async (jid) => {
126
+ const node = buildBlocklistChangeIq(jid, 'unblock');
127
+ const result = await queryWithContext('privacy.unblockUser', node, undefined, { jid });
128
+ assertIqResult(result, 'privacy.unblockUser');
129
+ }
130
+ };
131
+ }
@@ -0,0 +1,211 @@
1
+ import { buildDeleteProfilePictureIq, buildGetDisappearingModeUsyncQueryNode, buildGetProfilePictureIq, buildGetStatusUsyncQueryNodes, buildSetProfilePictureIq, buildSetStatusIq } from '../../transport/node/builders/profile.js';
2
+ import { buildUsyncIq } from '../../transport/node/builders/usync.js';
3
+ import { findNodeChild, getNodeChildren } from '../../transport/node/helpers.js';
4
+ import { assertIqResult } from '../../transport/node/query.js';
5
+ import { TEXT_DECODER } from '../../util/bytes.js';
6
+ function parseProfilePicture(result) {
7
+ const pictureNode = findNodeChild(result, 'picture');
8
+ if (!pictureNode) {
9
+ return {};
10
+ }
11
+ return {
12
+ url: pictureNode.attrs.url,
13
+ directPath: pictureNode.attrs.direct_path,
14
+ id: pictureNode.attrs.id,
15
+ type: pictureNode.attrs.type
16
+ };
17
+ }
18
+ function parseSetPictureResult(result) {
19
+ const pictureNode = findNodeChild(result, 'picture');
20
+ return pictureNode?.attrs.id ?? null;
21
+ }
22
+ function parseUsyncProfiles(result) {
23
+ const usyncNode = findNodeChild(result, 'usync');
24
+ if (!usyncNode) {
25
+ return [];
26
+ }
27
+ const listNode = findNodeChild(usyncNode, 'list');
28
+ if (!listNode) {
29
+ return [];
30
+ }
31
+ const userNodes = getNodeChildren(listNode);
32
+ const profiles = new Array(userNodes.length);
33
+ let count = 0;
34
+ for (let i = 0; i < userNodes.length; i += 1) {
35
+ const userNode = userNodes[i];
36
+ if (userNode.tag !== 'user') {
37
+ continue;
38
+ }
39
+ const jid = userNode.attrs.jid;
40
+ if (!jid) {
41
+ continue;
42
+ }
43
+ const info = { jid };
44
+ const userContent = userNode.content;
45
+ if (!Array.isArray(userContent)) {
46
+ profiles[count] = info;
47
+ count += 1;
48
+ continue;
49
+ }
50
+ for (let j = 0; j < userContent.length; j += 1) {
51
+ const child = userContent[j];
52
+ if (child.tag === 'picture') {
53
+ const idAttr = child.attrs.id;
54
+ if (idAttr) {
55
+ const parsed = Number.parseInt(idAttr, 10);
56
+ if (Number.isSafeInteger(parsed)) {
57
+ info.pictureId = parsed;
58
+ }
59
+ }
60
+ }
61
+ else if (child.tag === 'status') {
62
+ const code = child.attrs.code;
63
+ if (code !== undefined && Number.parseInt(code, 10) === 401) {
64
+ info.status = '';
65
+ }
66
+ else {
67
+ const content = child.content;
68
+ if (content instanceof Uint8Array) {
69
+ const decoded = TEXT_DECODER.decode(content);
70
+ info.status = decoded.length > 0 ? decoded : null;
71
+ }
72
+ else if (typeof content === 'string') {
73
+ info.status = content.length > 0 ? content : null;
74
+ }
75
+ else {
76
+ info.status = null;
77
+ }
78
+ }
79
+ }
80
+ }
81
+ profiles[count] = info;
82
+ count += 1;
83
+ }
84
+ profiles.length = count;
85
+ return profiles;
86
+ }
87
+ function parseUsyncDisappearingModes(result) {
88
+ const usyncNode = findNodeChild(result, 'usync');
89
+ if (!usyncNode)
90
+ return [];
91
+ const listNode = findNodeChild(usyncNode, 'list');
92
+ if (!listNode)
93
+ return [];
94
+ const userNodes = getNodeChildren(listNode);
95
+ const results = new Array(userNodes.length);
96
+ let count = 0;
97
+ for (let i = 0; i < userNodes.length; i += 1) {
98
+ const userNode = userNodes[i];
99
+ if (userNode.tag !== 'user')
100
+ continue;
101
+ const userContent = userNode.content;
102
+ if (!Array.isArray(userContent))
103
+ continue;
104
+ for (let j = 0; j < userContent.length; j += 1) {
105
+ const child = userContent[j];
106
+ if (child.tag !== 'disappearing_mode')
107
+ continue;
108
+ const errorNode = findNodeChild(child, 'error');
109
+ if (errorNode)
110
+ continue;
111
+ const duration = Number.parseInt(child.attrs.duration ?? '0', 10);
112
+ const timestamp = Number.parseInt(child.attrs.t ?? '0', 10);
113
+ const entry = { duration, timestamp };
114
+ if (child.attrs.ephemerality_disabled === 'true') {
115
+ entry.ephemeralityDisabled = true;
116
+ }
117
+ results[count] = entry;
118
+ count += 1;
119
+ }
120
+ }
121
+ results.length = count;
122
+ return results;
123
+ }
124
+ function parseUsyncStatus(result) {
125
+ const profiles = parseUsyncProfiles(result);
126
+ if (profiles.length === 0) {
127
+ return { status: null };
128
+ }
129
+ return { status: profiles[0].status ?? null };
130
+ }
131
+ export function createProfileCoordinator(options) {
132
+ const { queryWithContext, generateSid } = options;
133
+ return {
134
+ getProfilePicture: async (jid, type, existingId) => {
135
+ const node = buildGetProfilePictureIq(jid, type, existingId);
136
+ const result = await queryWithContext('profile.getPicture', node, undefined, {
137
+ jid,
138
+ type: type ?? 'preview'
139
+ });
140
+ assertIqResult(result, 'profile.getPicture');
141
+ return parseProfilePicture(result);
142
+ },
143
+ setProfilePicture: async (imageBytes, targetJid) => {
144
+ const node = buildSetProfilePictureIq(imageBytes, targetJid);
145
+ const result = await queryWithContext('profile.setPicture', node, undefined, {
146
+ targetJid,
147
+ size: imageBytes.length
148
+ });
149
+ assertIqResult(result, 'profile.setPicture');
150
+ return parseSetPictureResult(result);
151
+ },
152
+ deleteProfilePicture: async (targetJid) => {
153
+ const node = buildDeleteProfilePictureIq(targetJid);
154
+ const result = await queryWithContext('profile.deletePicture', node, undefined, {
155
+ targetJid
156
+ });
157
+ assertIqResult(result, 'profile.deletePicture');
158
+ },
159
+ getStatus: async (jid) => {
160
+ const sid = await generateSid();
161
+ const queryNodes = buildGetStatusUsyncQueryNodes();
162
+ const usyncNode = buildUsyncIq({
163
+ sid,
164
+ queryProtocolNodes: [queryNodes[1]],
165
+ users: [{ jid }]
166
+ });
167
+ const result = await queryWithContext('profile.getStatus', usyncNode, undefined, {
168
+ jid
169
+ });
170
+ assertIqResult(result, 'profile.getStatus');
171
+ return parseUsyncStatus(result);
172
+ },
173
+ setStatus: async (text) => {
174
+ const node = buildSetStatusIq(text);
175
+ const result = await queryWithContext('profile.setStatus', node, undefined, undefined, {
176
+ useSystemId: true
177
+ });
178
+ assertIqResult(result, 'profile.setStatus');
179
+ },
180
+ getProfiles: async (jids) => {
181
+ if (jids.length === 0) {
182
+ return [];
183
+ }
184
+ const sid = await generateSid();
185
+ const queryProtocolNodes = buildGetStatusUsyncQueryNodes();
186
+ const usyncNode = buildUsyncIq({
187
+ sid,
188
+ queryProtocolNodes,
189
+ users: jids.map((jid) => ({ jid }))
190
+ });
191
+ const result = await queryWithContext('profile.getProfiles', usyncNode, undefined, {
192
+ count: jids.length
193
+ });
194
+ assertIqResult(result, 'profile.getProfiles');
195
+ return parseUsyncProfiles(result);
196
+ },
197
+ getDisappearingMode: async (jids) => {
198
+ if (jids.length === 0)
199
+ return [];
200
+ const sid = await generateSid();
201
+ const usyncNode = buildUsyncIq({
202
+ sid,
203
+ queryProtocolNodes: [buildGetDisappearingModeUsyncQueryNode()],
204
+ users: jids.map((jid) => ({ jid }))
205
+ });
206
+ const result = await queryWithContext('profile.getDisappearingMode', usyncNode, undefined, { count: jids.length });
207
+ assertIqResult(result, 'profile.getDisappearingMode');
208
+ return parseUsyncDisappearingModes(result);
209
+ }
210
+ };
211
+ }