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
@@ -2,22 +2,27 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.WaMessageDispatchCoordinator = void 0;
4
4
  const _crypto_1 = require("../../crypto/index.js");
5
+ const primitives_1 = require("../../crypto/core/primitives");
6
+ const PromiseDedup_1 = require("../../infra/perf/PromiseDedup");
5
7
  const _message_1 = require("../../message/index.js");
6
8
  const content_1 = require("../../message/content");
7
9
  const device_sent_1 = require("../../message/device-sent");
10
+ const icdc_1 = require("../../message/icdc");
8
11
  const padding_1 = require("../../message/padding");
9
12
  const phash_1 = require("../../message/phash");
10
13
  const reporting_token_1 = require("../../message/reporting-token");
11
14
  const _proto_1 = require("../../proto.js");
12
15
  const constants_1 = require("../../protocol/constants");
13
16
  const jid_1 = require("../../protocol/jid");
14
- const jid_2 = require("../../protocol/jid");
15
17
  const binary_1 = require("../../transport/binary");
16
18
  const message_1 = require("../../transport/node/builders/message");
17
19
  const bytes_1 = require("../../util/bytes");
18
- const primitives_1 = require("../../util/primitives");
20
+ const primitives_2 = require("../../util/primitives");
19
21
  class WaMessageDispatchCoordinator {
20
22
  constructor(options) {
23
+ this.icdcDedup = new PromiseDedup_1.PromiseDedup();
24
+ this.privacyTokenDedup = new PromiseDedup_1.PromiseDedup();
25
+ this.distributionDedup = new PromiseDedup_1.PromiseDedup();
21
26
  this.logger = options.logger;
22
27
  this.messageClient = options.messageClient;
23
28
  this.retryTracker = options.retryTracker;
@@ -28,9 +33,18 @@ class WaMessageDispatchCoordinator {
28
33
  this.buildMessageContent = options.buildMessageContent;
29
34
  this.senderKeyManager = options.senderKeyManager;
30
35
  this.signalProtocol = options.signalProtocol;
36
+ this.signalStore = options.signalStore;
37
+ this.sessionStore = options.sessionStore;
38
+ this.identityStore = options.identityStore;
39
+ this.deviceListStore = options.deviceListStore;
40
+ this.messageSecretStore = options.messageSecretStore;
31
41
  this.getCurrentMeJid = options.getCurrentMeJid;
32
42
  this.getCurrentMeLid = options.getCurrentMeLid;
33
43
  this.getCurrentSignedIdentity = options.getCurrentSignedIdentity;
44
+ this.resolvePrivacyTokenNode = options.resolvePrivacyTokenNode;
45
+ this.onDirectMessageSent = options.onDirectMessageSent;
46
+ this.getIcdcHashLength = options.getIcdcHashLength;
47
+ this.mobileMessageIdFormat = options.mobileMessageIdFormat ?? false;
34
48
  }
35
49
  async publishMessageNode(node, options = {}) {
36
50
  this.logger.debug('wa client publish message node', {
@@ -71,7 +85,8 @@ class WaMessageDispatchCoordinator {
71
85
  toJid: input.to,
72
86
  type: input.type ?? 'text',
73
87
  replayPayload,
74
- participantJid: input.participant
88
+ participantJid: input.participant,
89
+ eligibleRequesterDeviceJids: [input.to]
75
90
  }, async () => this.messageClient.publishEncrypted(input, options));
76
91
  }
77
92
  async publishSignalMessage(input, options = {}) {
@@ -101,7 +116,8 @@ class WaMessageDispatchCoordinator {
101
116
  toJid: input.to,
102
117
  type: messageType,
103
118
  replayPayload,
104
- participantJid: input.participant
119
+ participantJid: input.participant,
120
+ eligibleRequesterDeviceJids: [input.to]
105
121
  }, async () => this.messageClient.publishEncrypted({
106
122
  to: input.to,
107
123
  encType: encrypted.type,
@@ -121,16 +137,47 @@ class WaMessageDispatchCoordinator {
121
137
  this.withResolvedMessageId(options)
122
138
  ]);
123
139
  const messageWithSecret = await (0, _message_1.ensureMessageSecret)(message);
124
- const plaintext = await (0, padding_1.writeRandomPadMax16)(_proto_1.proto.Message.encode(messageWithSecret).finish());
125
- const type = (0, content_1.resolveMessageTypeAttr)(messageWithSecret);
126
- if ((0, jid_1.isGroupJid)(recipientJid)) {
127
- if (this.shouldUseGroupDirectPath(messageWithSecret)) {
128
- return this.publishGroupDirectMessage(recipientJid, messageWithSecret, plaintext, type, sendOptions);
140
+ const rawSecret = messageWithSecret.messageContextInfo?.messageSecret;
141
+ if (rawSecret &&
142
+ rawSecret.length > 0 &&
143
+ sendOptions.id &&
144
+ (0, content_1.needsSecretPersistence)(messageWithSecret)) {
145
+ const meJid = this.getCurrentMeJid() ?? '';
146
+ void this.messageSecretStore
147
+ .set(sendOptions.id, { secret: rawSecret, senderJid: meJid })
148
+ .catch((error) => {
149
+ this.logger.warn('failed to persist outgoing message secret', {
150
+ id: sendOptions.id,
151
+ message: (0, primitives_2.toError)(error).message
152
+ });
153
+ });
154
+ }
155
+ const meJid = this.getCurrentMeJid();
156
+ const regInfo = meJid ? await this.signalStore.getRegistrationInfo() : null;
157
+ const localPubKey = regInfo?.identityKeyPair.pubKey;
158
+ const meParsed = meJid ? (0, jid_1.parseJidFull)(meJid) : undefined;
159
+ const meUserJid = meParsed?.userJid;
160
+ const localIdentity = meParsed && localPubKey ? { address: meParsed.address, pubKey: localPubKey } : undefined;
161
+ const isGroup = (0, jid_1.isGroupJid)(recipientJid);
162
+ const [senderIcdc, recipientIcdc] = await Promise.all([
163
+ meUserJid ? this.resolveUserIcdc(meUserJid, localIdentity) : null,
164
+ !isGroup ? this.resolveUserIcdc((0, jid_1.toUserJid)(recipientJid)) : null
165
+ ]);
166
+ const messageWithIcdc = (0, icdc_1.injectDeviceListMetadata)(messageWithSecret, senderIcdc, recipientIcdc);
167
+ const plaintext = await (0, padding_1.writeRandomPadMax16)(_proto_1.proto.Message.encode(messageWithIcdc).finish());
168
+ const type = (0, content_1.resolveMessageTypeAttr)(messageWithIcdc);
169
+ const edit = (0, content_1.resolveEditAttr)(messageWithIcdc, sendOptions.subtype) ?? undefined;
170
+ const mediatype = (0, content_1.resolveEncMediaType)(messageWithIcdc) ?? undefined;
171
+ const metaAttrs = (0, content_1.resolveMetaAttrs)(messageWithIcdc);
172
+ const metaNode = metaAttrs ? (0, message_1.buildMetaNode)(metaAttrs) : undefined;
173
+ if (isGroup) {
174
+ if (this.shouldUseGroupDirectPath(messageWithIcdc)) {
175
+ return this.publishGroupDirectMessage(recipientJid, messageWithIcdc, plaintext, type, sendOptions, {}, edit, mediatype, metaNode);
129
176
  }
130
- return this.publishGroupSenderKeyMessage(recipientJid, messageWithSecret, plaintext, type, sendOptions);
177
+ return this.publishGroupSenderKeyMessage(recipientJid, messageWithIcdc, plaintext, type, sendOptions, {}, edit, mediatype, metaNode);
131
178
  }
132
179
  const directRecipientJid = (0, jid_1.toUserJid)(recipientJid);
133
- return this.publishDirectSignalMessageWithFanout(directRecipientJid, messageWithSecret, plaintext, type, sendOptions);
180
+ return this.publishDirectSignalMessageWithFanout(directRecipientJid, messageWithIcdc, plaintext, type, sendOptions, edit, mediatype, metaNode);
134
181
  }
135
182
  async syncSignalSession(jid, reasonIdentity = false) {
136
183
  const address = (0, jid_1.parseSignalAddressFromJid)(jid);
@@ -159,7 +206,7 @@ class WaMessageDispatchCoordinator {
159
206
  }
160
207
  return message.keepInChatMessage?.keepType === _proto_1.proto.KeepType.UNDO_KEEP_FOR_ALL;
161
208
  }
162
- async publishGroupDirectMessage(groupJid, message, plaintext, type, options, retryContext = {}) {
209
+ async publishGroupDirectMessage(groupJid, message, plaintext, type, options, retryContext = {}, edit, mediatype, metaNode) {
163
210
  const sendOptions = await this.withResolvedMessageId(options);
164
211
  const meJid = this.requireCurrentMeJid('sendMessage');
165
212
  const participantUserJids = retryContext.forceRefreshParticipants
@@ -172,37 +219,68 @@ class WaMessageDispatchCoordinator {
172
219
  if (fanoutDeviceJids.length === 0) {
173
220
  throw new Error('group direct send resolved no target devices');
174
221
  }
175
- await this.sessionResolver.ensureSessionsBatch(fanoutDeviceJids);
176
- const participantAddresses = fanoutDeviceJids.map((targetJid) => (0, jid_1.parseSignalAddressFromJid)(targetJid));
177
- const encryptedParticipants = await this.signalProtocol.encryptMessagesBatch(participantAddresses.map((address) => ({
178
- address,
179
- plaintext
180
- })));
181
- const participants = fanoutDeviceJids.map((targetJid, index) => ({
182
- jid: targetJid,
183
- encType: encryptedParticipants[index].type,
184
- ciphertext: encryptedParticipants[index].ciphertext
185
- }));
186
- const shouldAttachDeviceIdentity = participants.some((participant) => participant.encType === 'pkmsg');
187
- const localPhash = await (0, phash_1.computePhashV2)([...fanoutDeviceJids, senderForPhash]);
188
- const reportingArtifacts = await this.tryBuildReportingTokenArtifacts({
189
- message,
190
- stanzaId: sendOptions.id,
191
- senderUserJid: (0, jid_1.toUserJid)(senderForPhash),
192
- remoteJid: groupJid,
193
- context: 'group_direct'
194
- });
195
- const messageNode = (0, message_1.buildGroupDirectMessageNode)({
222
+ const resolvedFanoutTargets = await this.sessionResolver.ensureSessionsBatch(fanoutDeviceJids);
223
+ const uniqueNormalizedFanoutJids = new Set();
224
+ for (let index = 0; index < fanoutDeviceJids.length; index += 1) {
225
+ uniqueNormalizedFanoutJids.add((0, jid_1.normalizeDeviceJid)(fanoutDeviceJids[index]));
226
+ }
227
+ if (resolvedFanoutTargets.length !== uniqueNormalizedFanoutJids.size) {
228
+ throw new Error('group direct send resolved incomplete signal sessions');
229
+ }
230
+ const participantEncryptRequests = new Array(resolvedFanoutTargets.length);
231
+ for (let index = 0; index < resolvedFanoutTargets.length; index += 1) {
232
+ const target = resolvedFanoutTargets[index];
233
+ participantEncryptRequests[index] = {
234
+ address: target.address,
235
+ plaintext
236
+ };
237
+ }
238
+ const encryptedParticipants = await this.signalProtocol.encryptMessagesBatch(participantEncryptRequests, resolvedFanoutTargets);
239
+ const participants = new Array(resolvedFanoutTargets.length);
240
+ for (let index = 0; index < resolvedFanoutTargets.length; index += 1) {
241
+ const target = resolvedFanoutTargets[index];
242
+ participants[index] = {
243
+ jid: target.jid,
244
+ encType: encryptedParticipants[index].type,
245
+ ciphertext: encryptedParticipants[index].ciphertext
246
+ };
247
+ }
248
+ let shouldAttachDeviceIdentity = false;
249
+ for (let index = 0; index < participants.length; index += 1) {
250
+ if (participants[index].encType === 'pkmsg') {
251
+ shouldAttachDeviceIdentity = true;
252
+ break;
253
+ }
254
+ }
255
+ const phashTargets = new Array(resolvedFanoutTargets.length + 1);
256
+ for (let index = 0; index < resolvedFanoutTargets.length; index += 1) {
257
+ phashTargets[index] = resolvedFanoutTargets[index].jid;
258
+ }
259
+ phashTargets[resolvedFanoutTargets.length] = senderForPhash;
260
+ const [localPhash, reportingArtifacts] = await Promise.all([
261
+ (0, phash_1.computePhashV2)(phashTargets),
262
+ this.tryBuildReportingTokenArtifacts({
263
+ message,
264
+ stanzaId: sendOptions.id,
265
+ senderUserJid: (0, jid_1.toUserJid)(senderForPhash),
266
+ remoteJid: groupJid,
267
+ context: 'group_direct'
268
+ })
269
+ ]);
270
+ const messageNode = (0, message_1.buildDirectMessageFanoutNode)({
196
271
  to: groupJid,
197
272
  type,
198
273
  id: sendOptions.id,
274
+ edit,
199
275
  phash: localPhash,
200
276
  addressingMode,
201
277
  participants,
202
278
  deviceIdentity: shouldAttachDeviceIdentity
203
279
  ? this.getEncodedSignedDeviceIdentity()
204
280
  : undefined,
205
- reportingNode: reportingArtifacts?.node ?? undefined
281
+ reportingNode: reportingArtifacts?.node ?? undefined,
282
+ metaNode,
283
+ mediatype
206
284
  });
207
285
  const replayPayload = {
208
286
  mode: 'plaintext',
@@ -214,7 +292,8 @@ class WaMessageDispatchCoordinator {
214
292
  messageIdHint: sendOptions.id ?? messageNode.attrs.id,
215
293
  toJid: groupJid,
216
294
  type,
217
- replayPayload
295
+ replayPayload,
296
+ eligibleRequesterDeviceJids: undefined
218
297
  }, async () => this.messageClient.publishNode(messageNode, sendOptions));
219
298
  const ackError = result.ack.error;
220
299
  const serverPhash = result.ack.phash;
@@ -240,11 +319,11 @@ class WaMessageDispatchCoordinator {
240
319
  retried: true,
241
320
  forceRefreshParticipants: true,
242
321
  forceAddressingMode: serverAddressingMode
243
- });
322
+ }, edit, mediatype, metaNode);
244
323
  }
245
324
  return result;
246
325
  }
247
- async publishGroupSenderKeyMessage(groupJid, message, plaintext, type, options, retryContext = {}) {
326
+ async publishGroupSenderKeyMessage(groupJid, message, plaintext, type, options, retryContext = {}, edit, mediatype, metaNode) {
248
327
  const sendOptions = await this.withResolvedMessageId(options);
249
328
  const meJid = this.requireCurrentMeJid('sendMessage');
250
329
  const participantUserJids = retryContext.forceRefreshParticipants
@@ -254,23 +333,36 @@ class WaMessageDispatchCoordinator {
254
333
  this.resolveGroupAddressingMode(participantUserJids, groupJid);
255
334
  const senderJid = this.resolveSenderForAddressingMode(addressingMode, meJid);
256
335
  const sender = (0, jid_1.parseSignalAddressFromJid)(senderJid);
257
- const senderKeyDistributionMessage = await this.senderKeyManager.createSenderKeyDistributionMessage(groupJid, sender);
258
- const groupCiphertext = await this.senderKeyManager.encryptGroupMessage(groupJid, sender, plaintext);
259
- const distributionData = await this.encryptGroupDistributionParticipants(groupJid, sender, senderKeyDistributionMessage, participantUserJids);
336
+ const { distributionMessage: senderKeyDistributionMessage, ciphertext: groupCiphertext, keyId: senderKeyId } = await this.senderKeyManager.prepareGroupEncryption(groupJid, sender, plaintext);
337
+ const distributionData = await this.distributionDedup.run(`dist:${groupJid}:${senderKeyId}`, () => this.encryptGroupDistributionParticipants(groupJid, senderKeyId, senderKeyDistributionMessage, participantUserJids));
260
338
  const { fanoutDeviceJids, distributionParticipants } = distributionData;
261
- const shouldAttachDeviceIdentity = distributionParticipants.some((participant) => participant.encType === 'pkmsg');
262
- const localPhash = await (0, phash_1.computePhashV2)([...fanoutDeviceJids, senderJid]);
263
- const reportingArtifacts = await this.tryBuildReportingTokenArtifacts({
264
- message,
265
- stanzaId: sendOptions.id,
266
- senderUserJid: (0, jid_1.toUserJid)(senderJid),
267
- remoteJid: groupJid,
268
- context: 'group_sender_key'
269
- });
339
+ let shouldAttachDeviceIdentity = false;
340
+ for (let index = 0; index < distributionParticipants.length; index += 1) {
341
+ if (distributionParticipants[index].encType === 'pkmsg') {
342
+ shouldAttachDeviceIdentity = true;
343
+ break;
344
+ }
345
+ }
346
+ const phashTargets = new Array(fanoutDeviceJids.length + 1);
347
+ for (let index = 0; index < fanoutDeviceJids.length; index += 1) {
348
+ phashTargets[index] = fanoutDeviceJids[index];
349
+ }
350
+ phashTargets[fanoutDeviceJids.length] = senderJid;
351
+ const [localPhash, reportingArtifacts] = await Promise.all([
352
+ (0, phash_1.computePhashV2)(phashTargets),
353
+ this.tryBuildReportingTokenArtifacts({
354
+ message,
355
+ stanzaId: sendOptions.id,
356
+ senderUserJid: (0, jid_1.toUserJid)(senderJid),
357
+ remoteJid: groupJid,
358
+ context: 'group_sender_key'
359
+ })
360
+ ]);
270
361
  const messageNode = (0, message_1.buildGroupSenderKeyMessageNode)({
271
362
  to: groupJid,
272
363
  type,
273
364
  id: sendOptions.id,
365
+ edit,
274
366
  phash: localPhash,
275
367
  addressingMode,
276
368
  groupCiphertext: groupCiphertext.ciphertext,
@@ -278,7 +370,9 @@ class WaMessageDispatchCoordinator {
278
370
  deviceIdentity: shouldAttachDeviceIdentity
279
371
  ? this.getEncodedSignedDeviceIdentity()
280
372
  : undefined,
281
- reportingNode: reportingArtifacts?.node ?? undefined
373
+ reportingNode: reportingArtifacts?.node ?? undefined,
374
+ metaNode,
375
+ mediatype
282
376
  });
283
377
  const replayPayload = {
284
378
  mode: 'plaintext',
@@ -290,17 +384,21 @@ class WaMessageDispatchCoordinator {
290
384
  messageIdHint: sendOptions.id ?? messageNode.attrs.id,
291
385
  toJid: groupJid,
292
386
  type,
293
- replayPayload
387
+ replayPayload,
388
+ eligibleRequesterDeviceJids: undefined
294
389
  }, async () => this.messageClient.publishNode(messageNode, sendOptions));
295
- const distributedAddresses = distributionParticipants.map((participant) => participant.address);
390
+ const distributedAddresses = new Array(distributionParticipants.length);
391
+ for (let index = 0; index < distributionParticipants.length; index += 1) {
392
+ distributedAddresses[index] = distributionParticipants[index].address;
393
+ }
296
394
  try {
297
- await this.senderKeyManager.markSenderKeyDistributed(groupJid, sender, distributedAddresses);
395
+ await this.senderKeyManager.markSenderKeyDistributed(groupJid, senderKeyId, distributedAddresses);
298
396
  }
299
397
  catch (error) {
300
398
  this.logger.warn('failed to mark sender key distribution targets', {
301
399
  groupJid,
302
400
  participants: distributedAddresses.length,
303
- message: (0, primitives_1.toError)(error).message
401
+ message: (0, primitives_2.toError)(error).message
304
402
  });
305
403
  }
306
404
  const ackError = result.ack.error;
@@ -327,19 +425,14 @@ class WaMessageDispatchCoordinator {
327
425
  retried: true,
328
426
  forceRefreshParticipants: true,
329
427
  forceAddressingMode: serverAddressingMode
330
- });
428
+ }, edit, mediatype, metaNode);
331
429
  }
332
430
  return result;
333
431
  }
334
432
  resolveGroupAddressingMode(participantUserJids, groupJid) {
335
- for (const participantJid of participantUserJids) {
336
- try {
337
- if ((0, jid_1.splitJid)(participantJid).server === 'lid') {
338
- return 'lid';
339
- }
340
- }
341
- catch (error) {
342
- this.logger.trace('ignoring malformed participant jid in addressing mode resolution', { participantJid, message: (0, primitives_1.toError)(error).message });
433
+ for (let index = 0; index < participantUserJids.length; index += 1) {
434
+ if ((0, jid_1.isLidJid)(participantUserJids[index])) {
435
+ return 'lid';
343
436
  }
344
437
  }
345
438
  this.logger.trace('group addressing mode resolved to pn (default)', {
@@ -358,14 +451,14 @@ class WaMessageDispatchCoordinator {
358
451
  catch (error) {
359
452
  this.logger.trace('ignoring malformed me lid jid', {
360
453
  meLid,
361
- message: (0, primitives_1.toError)(error).message
454
+ message: (0, primitives_2.toError)(error).message
362
455
  });
363
456
  }
364
457
  }
365
458
  }
366
459
  return (0, jid_1.normalizeDeviceJid)(meJid);
367
460
  }
368
- async encryptGroupDistributionParticipants(groupJid, sender, senderKeyDistributionMessage, participantUserJids) {
461
+ async encryptGroupDistributionParticipants(groupJid, senderKeyId, senderKeyDistributionMessage, participantUserJids) {
369
462
  const distributionPayload = await (0, padding_1.writeRandomPadMax16)(_proto_1.proto.Message.encode({
370
463
  senderKeyDistributionMessage
371
464
  }).finish());
@@ -382,9 +475,9 @@ class WaMessageDispatchCoordinator {
382
475
  const jid = fanoutDeviceJids[index];
383
476
  const address = (0, jid_1.parseSignalAddressFromJid)(jid);
384
477
  fanoutAddresses[index] = address;
385
- fanoutTargetsByAddressKey.set((0, jid_2.signalAddressKey)(address), { jid, address });
478
+ fanoutTargetsByAddressKey.set((0, jid_1.signalAddressKey)(address), { jid, address });
386
479
  }
387
- const pendingAddresses = await this.senderKeyManager.filterParticipantsNeedingDistribution(groupJid, sender, fanoutAddresses);
480
+ const pendingAddresses = await this.senderKeyManager.filterParticipantsNeedingDistribution(groupJid, senderKeyId, fanoutAddresses);
388
481
  if (pendingAddresses.length === 0) {
389
482
  return {
390
483
  fanoutDeviceJids,
@@ -394,7 +487,7 @@ class WaMessageDispatchCoordinator {
394
487
  const pendingAddressKeys = new Set();
395
488
  const pendingTargets = [];
396
489
  for (let index = 0; index < pendingAddresses.length; index += 1) {
397
- const key = (0, jid_2.signalAddressKey)(pendingAddresses[index]);
490
+ const key = (0, jid_1.signalAddressKey)(pendingAddresses[index]);
398
491
  if (pendingAddressKeys.has(key)) {
399
492
  continue;
400
493
  }
@@ -414,50 +507,82 @@ class WaMessageDispatchCoordinator {
414
507
  for (let index = 0; index < pendingTargets.length; index += 1) {
415
508
  pendingTargetJids[index] = pendingTargets[index].jid;
416
509
  }
510
+ let availableTargets = [];
511
+ let prefetchedAvailableTargets;
417
512
  try {
418
- await this.sessionResolver.ensureSessionsBatch(pendingTargetJids);
513
+ const resolvedTargets = await this.sessionResolver.ensureSessionsBatch(pendingTargetJids);
514
+ availableTargets = resolvedTargets;
515
+ prefetchedAvailableTargets = resolvedTargets;
419
516
  }
420
517
  catch (error) {
518
+ const normalized = (0, primitives_2.toError)(error);
519
+ if (normalized.message === 'identity mismatch') {
520
+ throw normalized;
521
+ }
421
522
  this.logger.warn('group sender-key distribution session sync failed, continuing with available sessions', {
422
523
  groupJid,
423
524
  requested: pendingTargetJids.length,
424
- message: (0, primitives_1.toError)(error).message
525
+ message: normalized.message
425
526
  });
527
+ const pendingTargetAddresses = new Array(pendingTargets.length);
528
+ for (let index = 0; index < pendingTargets.length; index += 1) {
529
+ pendingTargetAddresses[index] = pendingTargets[index].address;
530
+ }
531
+ const hasPendingSessions = await this.sessionStore.hasSessions(pendingTargetAddresses);
532
+ const nextAvailableTargets = [];
533
+ for (let index = 0; index < pendingTargets.length; index += 1) {
534
+ if (hasPendingSessions[index]) {
535
+ nextAvailableTargets.push(pendingTargets[index]);
536
+ }
537
+ }
538
+ availableTargets = nextAvailableTargets;
426
539
  }
427
- const hasPendingSessions = await this.signalProtocol.hasSessions(pendingTargets.map((target) => target.address));
428
- const availableTargets = pendingTargets.filter((_target, index) => hasPendingSessions[index]);
429
540
  if (availableTargets.length === 0) {
430
541
  return {
431
542
  fanoutDeviceJids,
432
543
  distributionParticipants: []
433
544
  };
434
545
  }
435
- const encryptedDistributionParticipants = await this.signalProtocol.encryptMessagesBatch(availableTargets.map((target) => ({
436
- address: target.address,
437
- plaintext: distributionPayload
438
- })));
439
- const distributionParticipants = availableTargets.map((target, index) => ({
440
- jid: target.jid,
441
- address: target.address,
442
- encType: encryptedDistributionParticipants[index].type,
443
- ciphertext: encryptedDistributionParticipants[index].ciphertext
444
- }));
546
+ const distributionEncryptRequests = new Array(availableTargets.length);
547
+ for (let index = 0; index < availableTargets.length; index += 1) {
548
+ const target = availableTargets[index];
549
+ distributionEncryptRequests[index] = {
550
+ address: target.address,
551
+ plaintext: distributionPayload
552
+ };
553
+ }
554
+ const encryptedDistributionParticipants = await this.signalProtocol.encryptMessagesBatch(distributionEncryptRequests, prefetchedAvailableTargets);
555
+ const distributionParticipants = new Array(availableTargets.length);
556
+ for (let index = 0; index < availableTargets.length; index += 1) {
557
+ const target = availableTargets[index];
558
+ distributionParticipants[index] = {
559
+ jid: target.jid,
560
+ address: target.address,
561
+ encType: encryptedDistributionParticipants[index].type,
562
+ ciphertext: encryptedDistributionParticipants[index].ciphertext
563
+ };
564
+ }
445
565
  return {
446
566
  fanoutDeviceJids,
447
567
  distributionParticipants
448
568
  };
449
569
  }
450
- async publishDirectSignalMessageWithFanout(recipientJid, message, plaintext, type, options) {
570
+ async publishDirectSignalMessageWithFanout(recipientJid, message, plaintext, type, options, edit, mediatype, metaNode) {
451
571
  const sendOptions = await this.withResolvedMessageId(options);
452
572
  const meJid = this.requireCurrentMeJid('sendMessage');
453
573
  const meLid = this.getCurrentMeLid();
454
574
  const selfDeviceJidForRecipient = this.fanoutResolver.resolveSelfDeviceJidForRecipient(recipientJid, meJid, meLid);
455
575
  const deviceJids = await this.fanoutResolver.resolveDirectFanoutDeviceJids(recipientJid, selfDeviceJidForRecipient);
456
- const targets = deviceJids.map((jid) => ({
457
- jid,
458
- normalizedJid: (0, jid_1.normalizeDeviceJid)(jid),
459
- userJid: (0, jid_1.toUserJid)(jid)
460
- }));
576
+ const targets = new Array(deviceJids.length);
577
+ for (let index = 0; index < deviceJids.length; index += 1) {
578
+ const jid = deviceJids[index];
579
+ const parsed = (0, jid_1.parseJidFull)(jid);
580
+ targets[index] = {
581
+ jid,
582
+ normalizedJid: parsed.normalizedJid,
583
+ userJid: parsed.userJid
584
+ };
585
+ }
461
586
  const recipientUserJid = (0, jid_1.toUserJid)(recipientJid);
462
587
  const meUserJid = (0, jid_1.toUserJid)(selfDeviceJidForRecipient);
463
588
  this.logger.debug('wa client publish signal fanout', {
@@ -474,30 +599,75 @@ class WaMessageDispatchCoordinator {
474
599
  }
475
600
  }
476
601
  }
477
- await this.sessionResolver.ensureSessionsBatch(deviceJids, expectedIdentityByJid);
478
- const hasSelfDeviceFanout = targets.some((target) => target.userJid === meUserJid);
602
+ const resolvedFanoutTargets = await this.sessionResolver.ensureSessionsBatch(deviceJids, expectedIdentityByJid);
603
+ const resolvedFanoutTargetsByJid = new Map();
604
+ for (let index = 0; index < resolvedFanoutTargets.length; index += 1) {
605
+ const target = resolvedFanoutTargets[index];
606
+ resolvedFanoutTargetsByJid.set((0, jid_1.normalizeDeviceJid)(target.jid), target);
607
+ }
608
+ for (let index = 0; index < targets.length; index += 1) {
609
+ if (!resolvedFanoutTargetsByJid.has(targets[index].normalizedJid)) {
610
+ throw new Error('direct fanout missing signal sessions for one or more targets');
611
+ }
612
+ }
613
+ let hasSelfDeviceFanout = false;
614
+ for (let index = 0; index < targets.length; index += 1) {
615
+ if (targets[index].userJid === meUserJid) {
616
+ hasSelfDeviceFanout = true;
617
+ break;
618
+ }
619
+ }
479
620
  const selfDevicePlaintext = hasSelfDeviceFanout
480
621
  ? await (0, padding_1.writeRandomPadMax16)(_proto_1.proto.Message.encode((0, device_sent_1.wrapDeviceSentMessage)(message, recipientUserJid)).finish())
481
622
  : null;
482
- const participantRequests = targets.map((target) => ({
483
- target,
484
- address: (0, jid_1.parseSignalAddressFromJid)(target.jid),
485
- expectedIdentity: target.userJid === recipientUserJid ? sendOptions.expectedIdentity : undefined,
486
- plaintext: selfDevicePlaintext && target.userJid === meUserJid
487
- ? selfDevicePlaintext
488
- : plaintext
489
- }));
490
- const encryptedParticipants = await this.signalProtocol.encryptMessagesBatch(participantRequests.map((request) => ({
491
- address: request.address,
492
- plaintext: request.plaintext,
493
- expectedIdentity: request.expectedIdentity
494
- })));
495
- const participants = participantRequests.map((request, index) => ({
496
- jid: request.target.jid,
497
- encType: encryptedParticipants[index].type,
498
- ciphertext: encryptedParticipants[index].ciphertext
499
- }));
500
- const shouldAttachDeviceIdentity = participants.some((participant) => participant.encType === 'pkmsg');
623
+ const participantRequests = new Array(targets.length);
624
+ for (let index = 0; index < targets.length; index += 1) {
625
+ const target = targets[index];
626
+ const resolvedTarget = resolvedFanoutTargetsByJid.get(target.normalizedJid);
627
+ if (!resolvedTarget) {
628
+ throw new Error('direct fanout missing signal session for target');
629
+ }
630
+ participantRequests[index] = {
631
+ target,
632
+ address: resolvedTarget.address,
633
+ session: resolvedTarget.session,
634
+ expectedIdentity: target.userJid === recipientUserJid ? sendOptions.expectedIdentity : undefined,
635
+ plaintext: selfDevicePlaintext && target.userJid === meUserJid
636
+ ? selfDevicePlaintext
637
+ : plaintext
638
+ };
639
+ }
640
+ const encryptRequests = new Array(participantRequests.length);
641
+ const prefetchedSessions = new Array(participantRequests.length);
642
+ for (let index = 0; index < participantRequests.length; index += 1) {
643
+ const request = participantRequests[index];
644
+ encryptRequests[index] = {
645
+ address: request.address,
646
+ plaintext: request.plaintext,
647
+ expectedIdentity: request.expectedIdentity
648
+ };
649
+ prefetchedSessions[index] = {
650
+ address: request.address,
651
+ session: request.session
652
+ };
653
+ }
654
+ const encryptedParticipants = await this.signalProtocol.encryptMessagesBatch(encryptRequests, prefetchedSessions);
655
+ const participants = new Array(participantRequests.length);
656
+ for (let index = 0; index < participantRequests.length; index += 1) {
657
+ const request = participantRequests[index];
658
+ participants[index] = {
659
+ jid: request.target.jid,
660
+ encType: encryptedParticipants[index].type,
661
+ ciphertext: encryptedParticipants[index].ciphertext
662
+ };
663
+ }
664
+ let shouldAttachDeviceIdentity = false;
665
+ for (let index = 0; index < participants.length; index += 1) {
666
+ if (participants[index].encType === 'pkmsg') {
667
+ shouldAttachDeviceIdentity = true;
668
+ break;
669
+ }
670
+ }
501
671
  const deviceIdentity = shouldAttachDeviceIdentity
502
672
  ? this.getEncodedSignedDeviceIdentity()
503
673
  : undefined;
@@ -508,13 +678,28 @@ class WaMessageDispatchCoordinator {
508
678
  remoteJid: recipientUserJid,
509
679
  context: 'direct_fanout'
510
680
  });
681
+ let privacyTokenNode;
682
+ try {
683
+ privacyTokenNode =
684
+ (await this.privacyTokenDedup.run(`pt:${recipientUserJid}`, () => this.resolvePrivacyTokenNode(recipientUserJid))) ?? undefined;
685
+ }
686
+ catch (error) {
687
+ this.logger.warn('privacy token resolution failed', {
688
+ to: recipientUserJid,
689
+ message: (0, primitives_2.toError)(error).message
690
+ });
691
+ }
511
692
  const messageNode = (0, message_1.buildDirectMessageFanoutNode)({
512
693
  to: recipientJid,
513
694
  type,
514
695
  id: sendOptions.id,
696
+ edit,
515
697
  participants,
516
698
  deviceIdentity,
517
- reportingNode: reportingArtifacts?.node ?? undefined
699
+ reportingNode: reportingArtifacts?.node ?? undefined,
700
+ privacyTokenNode,
701
+ metaNode,
702
+ mediatype
518
703
  });
519
704
  const replayPayload = {
520
705
  mode: 'plaintext',
@@ -522,12 +707,15 @@ class WaMessageDispatchCoordinator {
522
707
  type,
523
708
  plaintext
524
709
  };
525
- return this.retryTracker.track({
710
+ const result = await this.retryTracker.track({
526
711
  messageIdHint: sendOptions.id ?? messageNode.attrs.id,
527
712
  toJid: recipientJid,
528
713
  type,
529
- replayPayload
714
+ replayPayload,
715
+ eligibleRequesterDeviceJids: deviceJids
530
716
  }, async () => this.messageClient.publishNode(messageNode, sendOptions));
717
+ this.onDirectMessageSent(recipientUserJid);
718
+ return result;
531
719
  }
532
720
  async withResolvedMessageId(options) {
533
721
  const normalizedId = options.id?.trim();
@@ -548,9 +736,20 @@ class WaMessageDispatchCoordinator {
548
736
  async generateOutgoingMessageId() {
549
737
  try {
550
738
  const meUserJid = (0, jid_1.toUserJid)(this.requireCurrentMeJid('sendMessage'));
551
- const timestampSeconds = Math.floor(Date.now() / 1000);
552
739
  const timestampBytes = new Uint8Array(8);
553
- new DataView(timestampBytes.buffer, timestampBytes.byteOffset, timestampBytes.byteLength).setBigUint64(0, BigInt(timestampSeconds), false);
740
+ const dv = new DataView(timestampBytes.buffer, timestampBytes.byteOffset, timestampBytes.byteLength);
741
+ if (this.mobileMessageIdFormat) {
742
+ dv.setBigUint64(0, BigInt(Date.now()), false);
743
+ const entropy = (0, bytes_1.concatBytes)([
744
+ timestampBytes,
745
+ bytes_1.TEXT_ENCODER.encode(meUserJid),
746
+ await (0, _crypto_1.randomBytesAsync)(16)
747
+ ]);
748
+ const digest = (0, primitives_1.md5Bytes)(entropy);
749
+ digest[0] = 0xac;
750
+ return (0, bytes_1.bytesToHex)(digest).toUpperCase();
751
+ }
752
+ dv.setBigUint64(0, BigInt(Math.floor(Date.now() / 1000)), false);
554
753
  const entropy = (0, bytes_1.concatBytes)([
555
754
  timestampBytes,
556
755
  bytes_1.TEXT_ENCODER.encode(meUserJid),
@@ -560,9 +759,14 @@ class WaMessageDispatchCoordinator {
560
759
  return `3EB0${(0, bytes_1.bytesToHex)(digest.subarray(0, 9)).toUpperCase()}`;
561
760
  }
562
761
  catch (error) {
563
- this.logger.warn('failed to generate sha256 message id, falling back to random id', {
564
- message: (0, primitives_1.toError)(error).message
762
+ this.logger.warn('failed to generate message id, falling back to random', {
763
+ message: (0, primitives_2.toError)(error).message
565
764
  });
765
+ if (this.mobileMessageIdFormat) {
766
+ const bytes = await (0, _crypto_1.randomBytesAsync)(16);
767
+ bytes[0] = 0xac;
768
+ return (0, bytes_1.bytesToHex)(bytes).toUpperCase();
769
+ }
566
770
  return `3EB0${(0, bytes_1.bytesToHex)(await (0, _crypto_1.randomBytesAsync)(8)).toUpperCase()}`;
567
771
  }
568
772
  }
@@ -583,7 +787,7 @@ class WaMessageDispatchCoordinator {
583
787
  context: input.context,
584
788
  id: input.stanzaId,
585
789
  remoteJid: input.remoteJid,
586
- message: (0, primitives_1.toError)(error).message
790
+ message: (0, primitives_2.toError)(error).message
587
791
  });
588
792
  return null;
589
793
  }
@@ -591,10 +795,29 @@ class WaMessageDispatchCoordinator {
591
795
  getEncodedSignedDeviceIdentity() {
592
796
  const signedIdentity = this.getCurrentSignedIdentity();
593
797
  if (!signedIdentity) {
594
- throw new Error('missing signed identity for pkmsg fanout');
798
+ return undefined;
595
799
  }
596
800
  return _proto_1.proto.ADVSignedDeviceIdentity.encode(signedIdentity).finish();
597
801
  }
802
+ resolveUserIcdc(userJid, localIdentity) {
803
+ return this.icdcDedup.run(`icdc:${userJid}:${localIdentity ? '1' : '0'}`, async () => {
804
+ try {
805
+ const snapshots = await this.deviceListStore.getUserDevicesBatch([userJid]);
806
+ const snapshot = snapshots[0];
807
+ if (!snapshot || snapshot.deviceJids.length === 0) {
808
+ return null;
809
+ }
810
+ return (0, icdc_1.resolveIcdcMeta)(snapshot.deviceJids, this.identityStore, snapshot.updatedAtMs, localIdentity, this.getIcdcHashLength?.());
811
+ }
812
+ catch (error) {
813
+ this.logger.trace('icdc resolution failed', {
814
+ userJid,
815
+ message: (0, primitives_2.toError)(error).message
816
+ });
817
+ return null;
818
+ }
819
+ });
820
+ }
598
821
  requireCurrentMeJid(context) {
599
822
  const meJid = this.getCurrentMeJid();
600
823
  if (meJid) {