zapo-js 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (468) hide show
  1. package/README.md +12 -4
  2. package/dist/appstate/WaAppStateCrypto.js +1 -1
  3. package/dist/appstate/WaAppStateSyncClient.js +138 -93
  4. package/dist/appstate/{store/sqlite.js → encoding.js} +13 -8
  5. package/dist/appstate/index.js +8 -6
  6. package/dist/appstate/utils.js +0 -5
  7. package/dist/auth/WaAuthClient.js +36 -47
  8. package/dist/auth/flow/WaAuthCredentialsFlow.js +7 -7
  9. package/dist/auth/index.js +1 -6
  10. package/dist/auth/pairing/WaPairingCodeCrypto.js +6 -4
  11. package/dist/auth/pairing/WaPairingFlow.js +13 -3
  12. package/dist/client/WaClient.js +225 -101
  13. package/dist/client/WaClientFactory.js +294 -44
  14. package/dist/client/connection/WaConnectionManager.js +19 -10
  15. package/dist/client/coordinators/WaBusinessCoordinator.js +241 -0
  16. package/dist/client/coordinators/WaGroupCoordinator.js +11 -7
  17. package/dist/client/coordinators/WaIncomingNodeCoordinator.js +1 -0
  18. package/dist/client/coordinators/WaMessageDispatchCoordinator.js +292 -99
  19. package/dist/client/coordinators/WaPassiveTasksCoordinator.js +74 -31
  20. package/dist/client/coordinators/WaPrivacyCoordinator.js +134 -0
  21. package/dist/client/coordinators/WaProfileCoordinator.js +212 -0
  22. package/dist/client/coordinators/WaRetryCoordinator.js +179 -27
  23. package/dist/client/coordinators/WaStreamControlCoordinator.js +18 -11
  24. package/dist/client/coordinators/WaTrustedContactTokenCoordinator.js +166 -0
  25. package/dist/client/dirty.js +40 -20
  26. package/dist/client/events/devices.js +72 -0
  27. package/dist/client/events/group.js +3 -11
  28. package/dist/client/events/identity.js +22 -0
  29. package/dist/client/events/privacy-token.js +39 -0
  30. package/dist/client/history-sync.js +50 -9
  31. package/dist/client/incoming.js +37 -7
  32. package/dist/client/mailbox.js +24 -23
  33. package/dist/client/messages.js +107 -31
  34. package/dist/client/messaging/fanout.js +21 -11
  35. package/dist/client/messaging/participants.js +6 -4
  36. package/dist/client/persistence/WriteBehindPersistence.js +129 -0
  37. package/dist/client/tokens/cs-token.js +50 -0
  38. package/dist/client/tokens/tc-token.js +25 -0
  39. package/dist/crypto/core/index.js +2 -2
  40. package/dist/crypto/core/keys.js +4 -4
  41. package/dist/crypto/core/nonce.js +2 -0
  42. package/dist/crypto/core/primitives.js +0 -8
  43. package/dist/crypto/core/random.js +22 -0
  44. package/dist/crypto/curves/X25519.js +25 -6
  45. package/dist/crypto/index.js +3 -0
  46. package/dist/crypto/math/constants.js +13 -36
  47. package/dist/crypto/math/edwards.js +171 -44
  48. package/dist/crypto/math/fe.js +706 -0
  49. package/dist/crypto/math/mod.js +10 -3
  50. package/dist/esm/appstate/WaAppStateCrypto.js +1 -1
  51. package/dist/esm/appstate/WaAppStateSyncClient.js +138 -93
  52. package/dist/esm/appstate/{store/sqlite.js → encoding.js} +13 -8
  53. package/dist/esm/appstate/index.js +2 -2
  54. package/dist/esm/appstate/utils.js +2 -5
  55. package/dist/esm/auth/WaAuthClient.js +36 -47
  56. package/dist/esm/auth/flow/WaAuthCredentialsFlow.js +7 -7
  57. package/dist/esm/auth/index.js +0 -2
  58. package/dist/esm/auth/pairing/WaPairingCodeCrypto.js +6 -4
  59. package/dist/esm/auth/pairing/WaPairingFlow.js +14 -4
  60. package/dist/esm/client/WaClient.js +225 -101
  61. package/dist/esm/client/WaClientFactory.js +295 -45
  62. package/dist/esm/client/connection/WaConnectionManager.js +19 -10
  63. package/dist/esm/client/coordinators/WaBusinessCoordinator.js +238 -0
  64. package/dist/esm/client/coordinators/WaGroupCoordinator.js +11 -7
  65. package/dist/esm/client/coordinators/WaIncomingNodeCoordinator.js +1 -0
  66. package/dist/esm/client/coordinators/WaMessageDispatchCoordinator.js +295 -102
  67. package/dist/esm/client/coordinators/WaPassiveTasksCoordinator.js +74 -31
  68. package/dist/esm/client/coordinators/WaPrivacyCoordinator.js +131 -0
  69. package/dist/esm/client/coordinators/WaProfileCoordinator.js +209 -0
  70. package/dist/esm/client/coordinators/WaRetryCoordinator.js +181 -29
  71. package/dist/esm/client/coordinators/WaStreamControlCoordinator.js +19 -12
  72. package/dist/esm/client/coordinators/WaTrustedContactTokenCoordinator.js +162 -0
  73. package/dist/esm/client/dirty.js +40 -20
  74. package/dist/esm/client/events/devices.js +68 -0
  75. package/dist/esm/client/events/group.js +3 -11
  76. package/dist/esm/client/events/identity.js +19 -0
  77. package/dist/esm/client/events/privacy-token.js +36 -0
  78. package/dist/esm/client/history-sync.js +50 -9
  79. package/dist/esm/client/incoming.js +38 -8
  80. package/dist/esm/client/mailbox.js +24 -23
  81. package/dist/esm/client/messages.js +108 -32
  82. package/dist/esm/client/messaging/fanout.js +22 -12
  83. package/dist/esm/client/messaging/participants.js +6 -4
  84. package/dist/esm/client/persistence/WriteBehindPersistence.js +125 -0
  85. package/dist/esm/client/tokens/cs-token.js +46 -0
  86. package/dist/esm/client/tokens/tc-token.js +18 -0
  87. package/dist/esm/crypto/core/index.js +2 -2
  88. package/dist/esm/crypto/core/keys.js +1 -1
  89. package/dist/esm/crypto/core/nonce.js +2 -0
  90. package/dist/esm/crypto/core/primitives.js +0 -7
  91. package/dist/esm/crypto/core/random.js +22 -1
  92. package/dist/esm/crypto/curves/X25519.js +25 -6
  93. package/dist/esm/crypto/index.js +1 -0
  94. package/dist/esm/crypto/math/constants.js +12 -35
  95. package/dist/esm/crypto/math/edwards.js +174 -47
  96. package/dist/esm/crypto/math/fe.js +691 -0
  97. package/dist/esm/crypto/math/mod.js +10 -1
  98. package/dist/esm/index.js +1 -1
  99. package/dist/esm/infra/perf/BackgroundQueue.js +478 -0
  100. package/dist/esm/infra/perf/BoundedTaskQueue.js +3 -1
  101. package/dist/esm/infra/perf/PromiseDedup.js +20 -0
  102. package/dist/esm/infra/perf/SharedExclusiveGate.js +109 -0
  103. package/dist/esm/infra/perf/StoreLock.js +77 -0
  104. package/dist/esm/media/WaMediaCrypto.js +95 -13
  105. package/dist/esm/media/WaMediaTransferClient.js +39 -47
  106. package/dist/esm/media/constants.js +2 -1
  107. package/dist/esm/message/WaMessageClient.js +26 -19
  108. package/dist/esm/message/content.js +195 -9
  109. package/dist/esm/message/icdc.js +76 -0
  110. package/dist/esm/message/incoming.js +24 -12
  111. package/dist/esm/message/phash.js +3 -1
  112. package/dist/esm/message/reporting-token.js +14 -27
  113. package/dist/esm/protocol/appstate.js +9 -40
  114. package/dist/esm/protocol/browser.js +10 -18
  115. package/dist/esm/protocol/constants.js +5 -3
  116. package/dist/esm/protocol/defaults.js +6 -0
  117. package/dist/esm/protocol/index.js +1 -2
  118. package/dist/esm/protocol/jid.js +105 -36
  119. package/dist/esm/protocol/message.js +61 -1
  120. package/dist/esm/protocol/nodes.js +2 -0
  121. package/dist/esm/protocol/notification.js +3 -1
  122. package/dist/esm/protocol/privacy-token.js +17 -0
  123. package/dist/esm/protocol/privacy.js +55 -0
  124. package/dist/esm/protocol/stream.js +26 -1
  125. package/dist/esm/retry/codec.js +216 -0
  126. package/dist/esm/retry/constants.js +1 -1
  127. package/dist/esm/retry/index.js +2 -2
  128. package/dist/esm/retry/parse.js +50 -30
  129. package/dist/esm/retry/replay.js +11 -7
  130. package/dist/esm/retry/tracker.js +50 -12
  131. package/dist/esm/signal/api/SignalDeviceSyncApi.js +49 -32
  132. package/dist/esm/signal/api/SignalDigestSyncApi.js +13 -9
  133. package/dist/esm/signal/api/SignalIdentitySyncApi.js +26 -11
  134. package/dist/esm/signal/api/SignalMissingPreKeysSyncApi.js +18 -7
  135. package/dist/esm/signal/api/SignalRotateKeyApi.js +4 -2
  136. package/dist/esm/signal/api/SignalSessionSyncApi.js +16 -7
  137. package/dist/esm/signal/api/result-map.js +10 -0
  138. package/dist/esm/signal/constants.js +0 -4
  139. package/dist/esm/signal/crypto/WaAdvSignature.js +12 -6
  140. package/dist/esm/signal/{store/sqlite.js → encoding.js} +78 -24
  141. package/dist/esm/signal/group/SenderKeyCodec.js +3 -2
  142. package/dist/esm/signal/group/SenderKeyManager.js +125 -106
  143. package/dist/esm/signal/index.js +1 -0
  144. package/dist/esm/signal/registration/keygen.js +6 -2
  145. package/dist/esm/signal/registration/utils.js +1 -0
  146. package/dist/esm/signal/session/SignalProtocol.js +150 -74
  147. package/dist/esm/signal/session/resolver.js +137 -102
  148. package/dist/esm/store/contracts/privacy-token.store.js +1 -0
  149. package/dist/esm/store/createStore.js +101 -187
  150. package/dist/esm/store/index.js +1 -10
  151. package/dist/esm/store/locks/appstate.lock.js +26 -0
  152. package/dist/esm/store/locks/auth.lock.js +15 -0
  153. package/dist/esm/store/locks/contact.lock.js +20 -0
  154. package/dist/esm/store/locks/device-list.lock.js +20 -0
  155. package/dist/esm/store/locks/message.lock.js +21 -0
  156. package/dist/esm/store/locks/participants.lock.js +20 -0
  157. package/dist/esm/store/locks/privacy-token.lock.js +18 -0
  158. package/dist/esm/store/locks/retry.lock.js +29 -0
  159. package/dist/esm/store/locks/sender-key.lock.js +52 -0
  160. package/dist/esm/store/locks/signal.lock.js +63 -0
  161. package/dist/esm/store/locks/thread.lock.js +21 -0
  162. package/dist/esm/store/noop.store.js +1 -1
  163. package/dist/esm/store/providers/memory/appstate.store.js +22 -24
  164. package/dist/esm/store/providers/memory/device-list.store.js +10 -5
  165. package/dist/esm/store/providers/memory/privacy-token.store.js +43 -0
  166. package/dist/esm/store/providers/memory/retry.store.js +77 -2
  167. package/dist/esm/store/providers/memory/sender-key.store.js +6 -1
  168. package/dist/esm/store/providers/memory/signal.store.js +36 -19
  169. package/dist/esm/transport/WaComms.js +3 -1
  170. package/dist/esm/transport/WaWebSocket.js +0 -6
  171. package/dist/esm/transport/binary/constants.js +0 -30
  172. package/dist/esm/transport/binary/decoder.js +4 -4
  173. package/dist/esm/transport/binary/encoder.js +8 -15
  174. package/dist/esm/transport/binary/index.js +0 -1
  175. package/dist/esm/transport/node/WaNodeOrchestrator.js +25 -19
  176. package/dist/esm/transport/node/builders/business.js +129 -0
  177. package/dist/esm/transport/node/builders/global.js +370 -0
  178. package/dist/esm/transport/node/builders/index.js +5 -2
  179. package/dist/esm/transport/node/builders/message.js +63 -239
  180. package/dist/esm/transport/node/builders/pairing.js +0 -24
  181. package/dist/esm/transport/node/builders/privacy-token.js +41 -0
  182. package/dist/esm/transport/node/builders/privacy.js +48 -0
  183. package/dist/esm/transport/node/builders/profile.js +70 -0
  184. package/dist/esm/transport/node/builders/retry.js +10 -22
  185. package/dist/esm/transport/node/builders/usync.js +6 -2
  186. package/dist/esm/transport/node/helpers.js +19 -1
  187. package/dist/esm/transport/node/usync.js +3 -33
  188. package/dist/esm/transport/node/xml.js +35 -14
  189. package/dist/esm/transport/noise/WaClientPayload.js +10 -10
  190. package/dist/esm/transport/noise/WaNoiseCert.js +3 -3
  191. package/dist/esm/transport/noise/WaNoiseSession.js +64 -23
  192. package/dist/esm/transport/noise/WaNoiseSocket.js +8 -4
  193. package/dist/esm/transport/stream/parse.js +8 -4
  194. package/dist/esm/util/bytes.js +22 -18
  195. package/dist/esm/util/index.js +5 -0
  196. package/dist/esm/util/primitives.js +3 -2
  197. package/dist/index.js +7 -1
  198. package/dist/infra/perf/BackgroundQueue.js +482 -0
  199. package/dist/infra/perf/BoundedTaskQueue.js +3 -1
  200. package/dist/infra/perf/PromiseDedup.js +24 -0
  201. package/dist/infra/perf/SharedExclusiveGate.js +113 -0
  202. package/dist/infra/perf/StoreLock.js +81 -0
  203. package/dist/media/WaMediaCrypto.js +94 -12
  204. package/dist/media/WaMediaTransferClient.js +39 -47
  205. package/dist/media/constants.js +2 -1
  206. package/dist/message/WaMessageClient.js +26 -19
  207. package/dist/message/content.js +198 -9
  208. package/dist/message/icdc.js +81 -0
  209. package/dist/message/incoming.js +24 -12
  210. package/dist/message/phash.js +3 -1
  211. package/dist/message/reporting-token.js +14 -28
  212. package/dist/protocol/appstate.js +10 -41
  213. package/dist/protocol/browser.js +10 -18
  214. package/dist/protocol/constants.js +21 -2
  215. package/dist/protocol/defaults.js +6 -0
  216. package/dist/protocol/index.js +8 -5
  217. package/dist/protocol/jid.js +111 -36
  218. package/dist/protocol/message.js +62 -2
  219. package/dist/protocol/nodes.js +2 -0
  220. package/dist/protocol/notification.js +3 -1
  221. package/dist/protocol/privacy-token.js +20 -0
  222. package/dist/protocol/privacy.js +58 -0
  223. package/dist/protocol/stream.js +27 -2
  224. package/dist/retry/codec.js +220 -0
  225. package/dist/retry/constants.js +1 -1
  226. package/dist/retry/index.js +5 -5
  227. package/dist/retry/parse.js +51 -30
  228. package/dist/retry/replay.js +10 -6
  229. package/dist/retry/tracker.js +50 -12
  230. package/dist/signal/api/SignalDeviceSyncApi.js +48 -31
  231. package/dist/signal/api/SignalDigestSyncApi.js +13 -9
  232. package/dist/signal/api/SignalIdentitySyncApi.js +25 -10
  233. package/dist/signal/api/SignalMissingPreKeysSyncApi.js +17 -6
  234. package/dist/signal/api/SignalRotateKeyApi.js +4 -2
  235. package/dist/signal/api/SignalSessionSyncApi.js +16 -7
  236. package/dist/signal/api/result-map.js +13 -0
  237. package/dist/signal/constants.js +1 -5
  238. package/dist/signal/crypto/WaAdvSignature.js +11 -5
  239. package/dist/signal/{store/sqlite.js → encoding.js} +79 -25
  240. package/dist/signal/group/SenderKeyCodec.js +4 -3
  241. package/dist/signal/group/SenderKeyManager.js +125 -106
  242. package/dist/signal/index.js +13 -1
  243. package/dist/signal/registration/keygen.js +6 -2
  244. package/dist/signal/registration/utils.js +1 -0
  245. package/dist/signal/session/SignalProtocol.js +150 -74
  246. package/dist/signal/session/resolver.js +135 -100
  247. package/dist/store/contracts/privacy-token.store.js +2 -0
  248. package/dist/store/createStore.js +101 -187
  249. package/dist/store/index.js +15 -33
  250. package/dist/store/locks/appstate.lock.js +29 -0
  251. package/dist/store/locks/auth.lock.js +18 -0
  252. package/dist/store/locks/contact.lock.js +23 -0
  253. package/dist/store/locks/device-list.lock.js +23 -0
  254. package/dist/store/locks/message.lock.js +24 -0
  255. package/dist/store/locks/participants.lock.js +23 -0
  256. package/dist/store/locks/privacy-token.lock.js +21 -0
  257. package/dist/store/locks/retry.lock.js +32 -0
  258. package/dist/store/locks/sender-key.lock.js +55 -0
  259. package/dist/store/locks/signal.lock.js +66 -0
  260. package/dist/store/locks/thread.lock.js +24 -0
  261. package/dist/store/noop.store.js +1 -1
  262. package/dist/store/providers/memory/appstate.store.js +22 -24
  263. package/dist/store/providers/memory/device-list.store.js +10 -5
  264. package/dist/store/providers/memory/privacy-token.store.js +47 -0
  265. package/dist/store/providers/memory/retry.store.js +77 -2
  266. package/dist/store/providers/memory/sender-key.store.js +6 -1
  267. package/dist/store/providers/memory/signal.store.js +36 -19
  268. package/dist/transport/WaComms.js +3 -1
  269. package/dist/transport/WaWebSocket.js +0 -6
  270. package/dist/transport/binary/constants.js +1 -31
  271. package/dist/transport/binary/decoder.js +4 -4
  272. package/dist/transport/binary/encoder.js +8 -15
  273. package/dist/transport/binary/index.js +0 -4
  274. package/dist/transport/node/WaNodeOrchestrator.js +24 -18
  275. package/dist/transport/node/builders/business.js +137 -0
  276. package/dist/transport/node/builders/global.js +375 -0
  277. package/dist/transport/node/builders/index.js +18 -9
  278. package/dist/transport/node/builders/message.js +64 -245
  279. package/dist/transport/node/builders/pairing.js +0 -26
  280. package/dist/transport/node/builders/privacy-token.js +46 -0
  281. package/dist/transport/node/builders/privacy.js +55 -0
  282. package/dist/transport/node/builders/profile.js +78 -0
  283. package/dist/transport/node/builders/retry.js +9 -21
  284. package/dist/transport/node/builders/usync.js +6 -2
  285. package/dist/transport/node/helpers.js +20 -1
  286. package/dist/transport/node/usync.js +2 -32
  287. package/dist/transport/node/xml.js +35 -14
  288. package/dist/transport/noise/WaClientPayload.js +13 -13
  289. package/dist/transport/noise/WaNoiseCert.js +2 -2
  290. package/dist/transport/noise/WaNoiseSession.js +64 -23
  291. package/dist/transport/noise/WaNoiseSocket.js +8 -4
  292. package/dist/transport/stream/parse.js +7 -3
  293. package/dist/types/appstate/encoding.d.ts +7 -0
  294. package/dist/types/appstate/index.d.ts +3 -3
  295. package/dist/types/appstate/utils.d.ts +0 -2
  296. package/dist/types/auth/flow/WaAuthCredentialsFlow.d.ts +1 -1
  297. package/dist/types/auth/index.d.ts +0 -2
  298. package/dist/types/auth/types.d.ts +1 -0
  299. package/dist/types/client/WaClient.d.ts +27 -12
  300. package/dist/types/client/WaClientFactory.d.ts +12 -4
  301. package/dist/types/client/connection/WaConnectionManager.d.ts +2 -0
  302. package/dist/types/client/coordinators/WaBusinessCoordinator.d.ts +57 -0
  303. package/dist/types/client/coordinators/WaIncomingNodeCoordinator.d.ts +3 -1
  304. package/dist/types/client/coordinators/WaMessageDispatchCoordinator.d.ts +14 -0
  305. package/dist/types/client/coordinators/WaPassiveTasksCoordinator.d.ts +4 -0
  306. package/dist/types/client/coordinators/WaPrivacyCoordinator.d.ts +26 -0
  307. package/dist/types/client/coordinators/WaProfileCoordinator.d.ts +36 -0
  308. package/dist/types/client/coordinators/WaRetryCoordinator.d.ts +6 -0
  309. package/dist/types/client/coordinators/WaStreamControlCoordinator.d.ts +3 -2
  310. package/dist/types/client/coordinators/WaTrustedContactTokenCoordinator.d.ts +45 -0
  311. package/dist/types/client/events/devices.d.ts +20 -0
  312. package/dist/types/client/events/identity.d.ts +9 -0
  313. package/dist/types/client/events/privacy-token.d.ts +7 -0
  314. package/dist/types/client/history-sync.d.ts +9 -6
  315. package/dist/types/client/incoming.d.ts +3 -1
  316. package/dist/types/client/index.d.ts +1 -1
  317. package/dist/types/client/mailbox.d.ts +3 -5
  318. package/dist/types/client/messages.d.ts +1 -2
  319. package/dist/types/client/persistence/WriteBehindPersistence.d.ts +34 -0
  320. package/dist/types/client/tokens/cs-token.d.ts +10 -0
  321. package/dist/types/client/tokens/tc-token.d.ts +5 -0
  322. package/dist/types/client/types.d.ts +51 -3
  323. package/dist/types/crypto/core/index.d.ts +2 -2
  324. package/dist/types/crypto/core/nonce.d.ts +2 -0
  325. package/dist/types/crypto/core/primitives.d.ts +0 -1
  326. package/dist/types/crypto/core/random.d.ts +1 -0
  327. package/dist/types/crypto/index.d.ts +1 -0
  328. package/dist/types/crypto/math/constants.d.ts +4 -2
  329. package/dist/types/crypto/math/fe.d.ts +30 -0
  330. package/dist/types/crypto/math/mod.d.ts +0 -2
  331. package/dist/types/crypto/math/types.d.ts +11 -4
  332. package/dist/types/index.d.ts +5 -3
  333. package/dist/types/infra/perf/BackgroundQueue.d.ts +58 -0
  334. package/dist/types/infra/perf/PromiseDedup.d.ts +4 -0
  335. package/dist/types/infra/perf/SharedExclusiveGate.d.ts +17 -0
  336. package/dist/types/infra/perf/StoreLock.d.ts +10 -0
  337. package/dist/types/media/WaMediaCrypto.d.ts +3 -2
  338. package/dist/types/media/WaMediaTransferClient.d.ts +3 -12
  339. package/dist/types/media/constants.d.ts +1 -1
  340. package/dist/types/media/index.d.ts +1 -1
  341. package/dist/types/media/types.d.ts +10 -2
  342. package/dist/types/message/content.d.ts +8 -0
  343. package/dist/types/message/icdc.d.ts +13 -0
  344. package/dist/types/message/reporting-token.d.ts +0 -1
  345. package/dist/types/message/types.d.ts +45 -6
  346. package/dist/types/protocol/appstate.d.ts +0 -11
  347. package/dist/types/protocol/constants.d.ts +7 -3
  348. package/dist/types/protocol/defaults.d.ts +6 -0
  349. package/dist/types/protocol/index.d.ts +1 -2
  350. package/dist/types/protocol/jid.d.ts +19 -2
  351. package/dist/types/protocol/message.d.ts +60 -0
  352. package/dist/types/protocol/nodes.d.ts +2 -0
  353. package/dist/types/protocol/notification.d.ts +2 -0
  354. package/dist/types/protocol/privacy-token.d.ts +17 -0
  355. package/dist/types/protocol/privacy.d.ts +75 -0
  356. package/dist/types/protocol/stream.d.ts +30 -0
  357. package/dist/types/retry/codec.d.ts +3 -0
  358. package/dist/types/retry/index.d.ts +3 -3
  359. package/dist/types/retry/parse.d.ts +5 -2
  360. package/dist/types/retry/tracker.d.ts +1 -0
  361. package/dist/types/retry/types.d.ts +6 -1
  362. package/dist/types/signal/api/SignalDeviceSyncApi.d.ts +2 -1
  363. package/dist/types/signal/api/SignalDigestSyncApi.d.ts +6 -0
  364. package/dist/types/signal/api/SignalIdentitySyncApi.d.ts +2 -0
  365. package/dist/types/signal/api/SignalRotateKeyApi.d.ts +4 -5
  366. package/dist/types/signal/api/SignalSessionSyncApi.d.ts +8 -6
  367. package/dist/types/signal/api/result-map.d.ts +1 -0
  368. package/dist/types/signal/constants.d.ts +0 -3
  369. package/dist/types/signal/{store/sqlite.d.ts → encoding.d.ts} +3 -3
  370. package/dist/types/signal/group/SenderKeyManager.d.ts +10 -5
  371. package/dist/types/signal/index.d.ts +2 -0
  372. package/dist/types/signal/session/SignalProtocol.d.ts +10 -4
  373. package/dist/types/signal/session/resolver.d.ts +7 -2
  374. package/dist/types/store/contracts/appstate.store.d.ts +1 -1
  375. package/dist/types/store/contracts/privacy-token.store.d.ts +16 -0
  376. package/dist/types/store/contracts/retry.store.d.ts +7 -0
  377. package/dist/types/store/contracts/signal.store.d.ts +7 -0
  378. package/dist/types/store/createStore.d.ts +1 -1
  379. package/dist/types/store/index.d.ts +5 -13
  380. package/dist/types/store/locks/appstate.lock.d.ts +3 -0
  381. package/dist/types/store/locks/auth.lock.d.ts +3 -0
  382. package/dist/types/store/locks/contact.lock.d.ts +3 -0
  383. package/dist/types/store/locks/device-list.lock.d.ts +2 -0
  384. package/dist/types/store/locks/message.lock.d.ts +3 -0
  385. package/dist/types/store/locks/participants.lock.d.ts +2 -0
  386. package/dist/types/store/locks/privacy-token.lock.d.ts +2 -0
  387. package/dist/types/store/locks/retry.lock.d.ts +2 -0
  388. package/dist/types/store/locks/sender-key.lock.d.ts +3 -0
  389. package/dist/types/store/locks/signal.lock.d.ts +3 -0
  390. package/dist/types/store/locks/thread.lock.d.ts +3 -0
  391. package/dist/types/store/providers/memory/appstate.store.d.ts +1 -1
  392. package/dist/types/store/providers/memory/privacy-token.store.d.ts +13 -0
  393. package/dist/types/store/providers/memory/retry.store.d.ts +8 -0
  394. package/dist/types/store/providers/memory/signal.store.d.ts +2 -1
  395. package/dist/types/store/types.d.ts +49 -61
  396. package/dist/types/transport/WaWebSocket.d.ts +0 -1
  397. package/dist/types/transport/binary/constants.d.ts +0 -30
  398. package/dist/types/transport/binary/index.d.ts +0 -1
  399. package/dist/types/transport/node/WaNodeOrchestrator.d.ts +3 -4
  400. package/dist/types/transport/node/builders/business.d.ts +29 -0
  401. package/dist/types/transport/node/builders/global.d.ts +102 -0
  402. package/dist/types/transport/node/builders/index.d.ts +5 -2
  403. package/dist/types/transport/node/builders/message.d.ts +8 -7
  404. package/dist/types/transport/node/builders/pairing.d.ts +0 -2
  405. package/dist/types/transport/node/builders/privacy-token.d.ts +9 -0
  406. package/dist/types/transport/node/builders/privacy.d.ts +7 -0
  407. package/dist/types/transport/node/builders/profile.d.ts +8 -0
  408. package/dist/types/transport/node/builders/retry.d.ts +0 -1
  409. package/dist/types/transport/node/helpers.d.ts +5 -0
  410. package/dist/types/transport/noise/WaNoiseSession.d.ts +3 -2
  411. package/dist/types/transport/noise/WaNoiseSocket.d.ts +4 -2
  412. package/dist/types/util/bytes.d.ts +1 -1
  413. package/dist/types/util/index.d.ts +5 -0
  414. package/dist/types/util/primitives.d.ts +0 -1
  415. package/dist/util/bytes.js +22 -18
  416. package/dist/util/index.js +23 -0
  417. package/dist/util/primitives.js +2 -2
  418. package/package.json +29 -7
  419. package/proto/index.js +1 -1
  420. package/dist/crypto/core/constants.js +0 -4
  421. package/dist/esm/crypto/core/constants.js +0 -1
  422. package/dist/esm/retry/outbound.js +0 -82
  423. package/dist/esm/store/providers/sqlite/BaseSqliteStore.js +0 -37
  424. package/dist/esm/store/providers/sqlite/appstate.store.js +0 -250
  425. package/dist/esm/store/providers/sqlite/auth.store.js +0 -176
  426. package/dist/esm/store/providers/sqlite/connection.js +0 -245
  427. package/dist/esm/store/providers/sqlite/contact.store.js +0 -74
  428. package/dist/esm/store/providers/sqlite/device-list.store.js +0 -127
  429. package/dist/esm/store/providers/sqlite/message.store.js +0 -132
  430. package/dist/esm/store/providers/sqlite/migrations.js +0 -347
  431. package/dist/esm/store/providers/sqlite/participants.store.js +0 -77
  432. package/dist/esm/store/providers/sqlite/retry.store.js +0 -141
  433. package/dist/esm/store/providers/sqlite/sender-key.store.js +0 -198
  434. package/dist/esm/store/providers/sqlite/signal.store.js +0 -435
  435. package/dist/esm/store/providers/sqlite/table-names.js +0 -107
  436. package/dist/esm/store/providers/sqlite/thread.store.js +0 -85
  437. package/dist/retry/outbound.js +0 -87
  438. package/dist/store/providers/sqlite/BaseSqliteStore.js +0 -41
  439. package/dist/store/providers/sqlite/appstate.store.js +0 -254
  440. package/dist/store/providers/sqlite/auth.store.js +0 -180
  441. package/dist/store/providers/sqlite/connection.js +0 -281
  442. package/dist/store/providers/sqlite/contact.store.js +0 -78
  443. package/dist/store/providers/sqlite/device-list.store.js +0 -131
  444. package/dist/store/providers/sqlite/message.store.js +0 -136
  445. package/dist/store/providers/sqlite/migrations.js +0 -350
  446. package/dist/store/providers/sqlite/participants.store.js +0 -81
  447. package/dist/store/providers/sqlite/retry.store.js +0 -145
  448. package/dist/store/providers/sqlite/sender-key.store.js +0 -202
  449. package/dist/store/providers/sqlite/signal.store.js +0 -439
  450. package/dist/store/providers/sqlite/table-names.js +0 -113
  451. package/dist/store/providers/sqlite/thread.store.js +0 -89
  452. package/dist/types/appstate/store/sqlite.d.ts +0 -7
  453. package/dist/types/crypto/core/constants.d.ts +0 -1
  454. package/dist/types/retry/outbound.d.ts +0 -4
  455. package/dist/types/store/providers/sqlite/BaseSqliteStore.d.ts +0 -12
  456. package/dist/types/store/providers/sqlite/appstate.store.d.ts +0 -17
  457. package/dist/types/store/providers/sqlite/auth.store.d.ts +0 -10
  458. package/dist/types/store/providers/sqlite/connection.d.ts +0 -10
  459. package/dist/types/store/providers/sqlite/contact.store.d.ts +0 -12
  460. package/dist/types/store/providers/sqlite/device-list.store.d.ts +0 -15
  461. package/dist/types/store/providers/sqlite/message.store.d.ts +0 -13
  462. package/dist/types/store/providers/sqlite/migrations.d.ts +0 -3
  463. package/dist/types/store/providers/sqlite/participants.store.d.ts +0 -12
  464. package/dist/types/store/providers/sqlite/retry.store.d.ts +0 -15
  465. package/dist/types/store/providers/sqlite/sender-key.store.d.ts +0 -24
  466. package/dist/types/store/providers/sqlite/signal.store.d.ts +0 -53
  467. package/dist/types/store/providers/sqlite/table-names.d.ts +0 -5
  468. package/dist/types/store/providers/sqlite/thread.store.d.ts +0 -13
@@ -2,9 +2,11 @@
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 PromiseDedup_1 = require("../../infra/perf/PromiseDedup");
5
6
  const _message_1 = require("../../message/index.js");
6
7
  const content_1 = require("../../message/content");
7
8
  const device_sent_1 = require("../../message/device-sent");
9
+ const icdc_1 = require("../../message/icdc");
8
10
  const padding_1 = require("../../message/padding");
9
11
  const phash_1 = require("../../message/phash");
10
12
  const reporting_token_1 = require("../../message/reporting-token");
@@ -18,6 +20,9 @@ const bytes_1 = require("../../util/bytes");
18
20
  const primitives_1 = 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,13 @@ 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.deviceListStore = options.deviceListStore;
31
38
  this.getCurrentMeJid = options.getCurrentMeJid;
32
39
  this.getCurrentMeLid = options.getCurrentMeLid;
33
40
  this.getCurrentSignedIdentity = options.getCurrentSignedIdentity;
41
+ this.resolvePrivacyTokenNode = options.resolvePrivacyTokenNode;
42
+ this.onDirectMessageSent = options.onDirectMessageSent;
34
43
  }
35
44
  async publishMessageNode(node, options = {}) {
36
45
  this.logger.debug('wa client publish message node', {
@@ -71,7 +80,8 @@ class WaMessageDispatchCoordinator {
71
80
  toJid: input.to,
72
81
  type: input.type ?? 'text',
73
82
  replayPayload,
74
- participantJid: input.participant
83
+ participantJid: input.participant,
84
+ eligibleRequesterDeviceJids: [input.to]
75
85
  }, async () => this.messageClient.publishEncrypted(input, options));
76
86
  }
77
87
  async publishSignalMessage(input, options = {}) {
@@ -101,7 +111,8 @@ class WaMessageDispatchCoordinator {
101
111
  toJid: input.to,
102
112
  type: messageType,
103
113
  replayPayload,
104
- participantJid: input.participant
114
+ participantJid: input.participant,
115
+ eligibleRequesterDeviceJids: [input.to]
105
116
  }, async () => this.messageClient.publishEncrypted({
106
117
  to: input.to,
107
118
  encType: encrypted.type,
@@ -121,16 +132,32 @@ class WaMessageDispatchCoordinator {
121
132
  this.withResolvedMessageId(options)
122
133
  ]);
123
134
  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);
135
+ const meJid = this.getCurrentMeJid();
136
+ const regInfo = meJid ? await this.signalStore.getRegistrationInfo() : null;
137
+ const localPubKey = regInfo?.identityKeyPair.pubKey;
138
+ const meParsed = meJid ? (0, jid_1.parseJidFull)(meJid) : undefined;
139
+ const meUserJid = meParsed?.userJid;
140
+ const localIdentity = meParsed && localPubKey ? { address: meParsed.address, pubKey: localPubKey } : undefined;
141
+ const isGroup = (0, jid_1.isGroupJid)(recipientJid);
142
+ const [senderIcdc, recipientIcdc] = await Promise.all([
143
+ meUserJid ? this.resolveUserIcdc(meUserJid, localIdentity) : null,
144
+ !isGroup ? this.resolveUserIcdc((0, jid_1.toUserJid)(recipientJid)) : null
145
+ ]);
146
+ const messageWithIcdc = (0, icdc_1.injectDeviceListMetadata)(messageWithSecret, senderIcdc, recipientIcdc);
147
+ const plaintext = await (0, padding_1.writeRandomPadMax16)(_proto_1.proto.Message.encode(messageWithIcdc).finish());
148
+ const type = (0, content_1.resolveMessageTypeAttr)(messageWithIcdc);
149
+ const edit = (0, content_1.resolveEditAttr)(messageWithIcdc, sendOptions.subtype) ?? undefined;
150
+ const mediatype = (0, content_1.resolveEncMediaType)(messageWithIcdc) ?? undefined;
151
+ const metaAttrs = (0, content_1.resolveMetaAttrs)(messageWithIcdc);
152
+ const metaNode = metaAttrs ? (0, message_1.buildMetaNode)(metaAttrs) : undefined;
153
+ if (isGroup) {
154
+ if (this.shouldUseGroupDirectPath(messageWithIcdc)) {
155
+ return this.publishGroupDirectMessage(recipientJid, messageWithIcdc, plaintext, type, sendOptions, {}, edit, mediatype, metaNode);
129
156
  }
130
- return this.publishGroupSenderKeyMessage(recipientJid, messageWithSecret, plaintext, type, sendOptions);
157
+ return this.publishGroupSenderKeyMessage(recipientJid, messageWithIcdc, plaintext, type, sendOptions, {}, edit, mediatype, metaNode);
131
158
  }
132
159
  const directRecipientJid = (0, jid_1.toUserJid)(recipientJid);
133
- return this.publishDirectSignalMessageWithFanout(directRecipientJid, messageWithSecret, plaintext, type, sendOptions);
160
+ return this.publishDirectSignalMessageWithFanout(directRecipientJid, messageWithIcdc, plaintext, type, sendOptions, edit, mediatype, metaNode);
134
161
  }
135
162
  async syncSignalSession(jid, reasonIdentity = false) {
136
163
  const address = (0, jid_1.parseSignalAddressFromJid)(jid);
@@ -159,7 +186,7 @@ class WaMessageDispatchCoordinator {
159
186
  }
160
187
  return message.keepInChatMessage?.keepType === _proto_1.proto.KeepType.UNDO_KEEP_FOR_ALL;
161
188
  }
162
- async publishGroupDirectMessage(groupJid, message, plaintext, type, options, retryContext = {}) {
189
+ async publishGroupDirectMessage(groupJid, message, plaintext, type, options, retryContext = {}, edit, mediatype, metaNode) {
163
190
  const sendOptions = await this.withResolvedMessageId(options);
164
191
  const meJid = this.requireCurrentMeJid('sendMessage');
165
192
  const participantUserJids = retryContext.forceRefreshParticipants
@@ -172,37 +199,68 @@ class WaMessageDispatchCoordinator {
172
199
  if (fanoutDeviceJids.length === 0) {
173
200
  throw new Error('group direct send resolved no target devices');
174
201
  }
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)({
202
+ const resolvedFanoutTargets = await this.sessionResolver.ensureSessionsBatch(fanoutDeviceJids);
203
+ const uniqueNormalizedFanoutJids = new Set();
204
+ for (let index = 0; index < fanoutDeviceJids.length; index += 1) {
205
+ uniqueNormalizedFanoutJids.add((0, jid_1.normalizeDeviceJid)(fanoutDeviceJids[index]));
206
+ }
207
+ if (resolvedFanoutTargets.length !== uniqueNormalizedFanoutJids.size) {
208
+ throw new Error('group direct send resolved incomplete signal sessions');
209
+ }
210
+ const participantEncryptRequests = new Array(resolvedFanoutTargets.length);
211
+ for (let index = 0; index < resolvedFanoutTargets.length; index += 1) {
212
+ const target = resolvedFanoutTargets[index];
213
+ participantEncryptRequests[index] = {
214
+ address: target.address,
215
+ plaintext
216
+ };
217
+ }
218
+ const encryptedParticipants = await this.signalProtocol.encryptMessagesBatch(participantEncryptRequests, resolvedFanoutTargets);
219
+ const participants = new Array(resolvedFanoutTargets.length);
220
+ for (let index = 0; index < resolvedFanoutTargets.length; index += 1) {
221
+ const target = resolvedFanoutTargets[index];
222
+ participants[index] = {
223
+ jid: target.jid,
224
+ encType: encryptedParticipants[index].type,
225
+ ciphertext: encryptedParticipants[index].ciphertext
226
+ };
227
+ }
228
+ let shouldAttachDeviceIdentity = false;
229
+ for (let index = 0; index < participants.length; index += 1) {
230
+ if (participants[index].encType === 'pkmsg') {
231
+ shouldAttachDeviceIdentity = true;
232
+ break;
233
+ }
234
+ }
235
+ const phashTargets = new Array(resolvedFanoutTargets.length + 1);
236
+ for (let index = 0; index < resolvedFanoutTargets.length; index += 1) {
237
+ phashTargets[index] = resolvedFanoutTargets[index].jid;
238
+ }
239
+ phashTargets[resolvedFanoutTargets.length] = senderForPhash;
240
+ const [localPhash, reportingArtifacts] = await Promise.all([
241
+ (0, phash_1.computePhashV2)(phashTargets),
242
+ this.tryBuildReportingTokenArtifacts({
243
+ message,
244
+ stanzaId: sendOptions.id,
245
+ senderUserJid: (0, jid_1.toUserJid)(senderForPhash),
246
+ remoteJid: groupJid,
247
+ context: 'group_direct'
248
+ })
249
+ ]);
250
+ const messageNode = (0, message_1.buildDirectMessageFanoutNode)({
196
251
  to: groupJid,
197
252
  type,
198
253
  id: sendOptions.id,
254
+ edit,
199
255
  phash: localPhash,
200
256
  addressingMode,
201
257
  participants,
202
258
  deviceIdentity: shouldAttachDeviceIdentity
203
259
  ? this.getEncodedSignedDeviceIdentity()
204
260
  : undefined,
205
- reportingNode: reportingArtifacts?.node ?? undefined
261
+ reportingNode: reportingArtifacts?.node ?? undefined,
262
+ metaNode,
263
+ mediatype
206
264
  });
207
265
  const replayPayload = {
208
266
  mode: 'plaintext',
@@ -214,7 +272,8 @@ class WaMessageDispatchCoordinator {
214
272
  messageIdHint: sendOptions.id ?? messageNode.attrs.id,
215
273
  toJid: groupJid,
216
274
  type,
217
- replayPayload
275
+ replayPayload,
276
+ eligibleRequesterDeviceJids: undefined
218
277
  }, async () => this.messageClient.publishNode(messageNode, sendOptions));
219
278
  const ackError = result.ack.error;
220
279
  const serverPhash = result.ack.phash;
@@ -240,11 +299,11 @@ class WaMessageDispatchCoordinator {
240
299
  retried: true,
241
300
  forceRefreshParticipants: true,
242
301
  forceAddressingMode: serverAddressingMode
243
- });
302
+ }, edit, mediatype, metaNode);
244
303
  }
245
304
  return result;
246
305
  }
247
- async publishGroupSenderKeyMessage(groupJid, message, plaintext, type, options, retryContext = {}) {
306
+ async publishGroupSenderKeyMessage(groupJid, message, plaintext, type, options, retryContext = {}, edit, mediatype, metaNode) {
248
307
  const sendOptions = await this.withResolvedMessageId(options);
249
308
  const meJid = this.requireCurrentMeJid('sendMessage');
250
309
  const participantUserJids = retryContext.forceRefreshParticipants
@@ -254,23 +313,36 @@ class WaMessageDispatchCoordinator {
254
313
  this.resolveGroupAddressingMode(participantUserJids, groupJid);
255
314
  const senderJid = this.resolveSenderForAddressingMode(addressingMode, meJid);
256
315
  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);
316
+ const { distributionMessage: senderKeyDistributionMessage, ciphertext: groupCiphertext, keyId: senderKeyId } = await this.senderKeyManager.prepareGroupEncryption(groupJid, sender, plaintext);
317
+ const distributionData = await this.distributionDedup.run(`dist:${groupJid}:${senderKeyId}`, () => this.encryptGroupDistributionParticipants(groupJid, senderKeyId, senderKeyDistributionMessage, participantUserJids));
260
318
  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
- });
319
+ let shouldAttachDeviceIdentity = false;
320
+ for (let index = 0; index < distributionParticipants.length; index += 1) {
321
+ if (distributionParticipants[index].encType === 'pkmsg') {
322
+ shouldAttachDeviceIdentity = true;
323
+ break;
324
+ }
325
+ }
326
+ const phashTargets = new Array(fanoutDeviceJids.length + 1);
327
+ for (let index = 0; index < fanoutDeviceJids.length; index += 1) {
328
+ phashTargets[index] = fanoutDeviceJids[index];
329
+ }
330
+ phashTargets[fanoutDeviceJids.length] = senderJid;
331
+ const [localPhash, reportingArtifacts] = await Promise.all([
332
+ (0, phash_1.computePhashV2)(phashTargets),
333
+ this.tryBuildReportingTokenArtifacts({
334
+ message,
335
+ stanzaId: sendOptions.id,
336
+ senderUserJid: (0, jid_1.toUserJid)(senderJid),
337
+ remoteJid: groupJid,
338
+ context: 'group_sender_key'
339
+ })
340
+ ]);
270
341
  const messageNode = (0, message_1.buildGroupSenderKeyMessageNode)({
271
342
  to: groupJid,
272
343
  type,
273
344
  id: sendOptions.id,
345
+ edit,
274
346
  phash: localPhash,
275
347
  addressingMode,
276
348
  groupCiphertext: groupCiphertext.ciphertext,
@@ -278,7 +350,9 @@ class WaMessageDispatchCoordinator {
278
350
  deviceIdentity: shouldAttachDeviceIdentity
279
351
  ? this.getEncodedSignedDeviceIdentity()
280
352
  : undefined,
281
- reportingNode: reportingArtifacts?.node ?? undefined
353
+ reportingNode: reportingArtifacts?.node ?? undefined,
354
+ metaNode,
355
+ mediatype
282
356
  });
283
357
  const replayPayload = {
284
358
  mode: 'plaintext',
@@ -290,11 +364,15 @@ class WaMessageDispatchCoordinator {
290
364
  messageIdHint: sendOptions.id ?? messageNode.attrs.id,
291
365
  toJid: groupJid,
292
366
  type,
293
- replayPayload
367
+ replayPayload,
368
+ eligibleRequesterDeviceJids: undefined
294
369
  }, async () => this.messageClient.publishNode(messageNode, sendOptions));
295
- const distributedAddresses = distributionParticipants.map((participant) => participant.address);
370
+ const distributedAddresses = new Array(distributionParticipants.length);
371
+ for (let index = 0; index < distributionParticipants.length; index += 1) {
372
+ distributedAddresses[index] = distributionParticipants[index].address;
373
+ }
296
374
  try {
297
- await this.senderKeyManager.markSenderKeyDistributed(groupJid, sender, distributedAddresses);
375
+ await this.senderKeyManager.markSenderKeyDistributed(groupJid, senderKeyId, distributedAddresses);
298
376
  }
299
377
  catch (error) {
300
378
  this.logger.warn('failed to mark sender key distribution targets', {
@@ -327,12 +405,13 @@ class WaMessageDispatchCoordinator {
327
405
  retried: true,
328
406
  forceRefreshParticipants: true,
329
407
  forceAddressingMode: serverAddressingMode
330
- });
408
+ }, edit, mediatype, metaNode);
331
409
  }
332
410
  return result;
333
411
  }
334
412
  resolveGroupAddressingMode(participantUserJids, groupJid) {
335
- for (const participantJid of participantUserJids) {
413
+ for (let index = 0; index < participantUserJids.length; index += 1) {
414
+ const participantJid = participantUserJids[index];
336
415
  try {
337
416
  if ((0, jid_1.splitJid)(participantJid).server === 'lid') {
338
417
  return 'lid';
@@ -365,7 +444,7 @@ class WaMessageDispatchCoordinator {
365
444
  }
366
445
  return (0, jid_1.normalizeDeviceJid)(meJid);
367
446
  }
368
- async encryptGroupDistributionParticipants(groupJid, sender, senderKeyDistributionMessage, participantUserJids) {
447
+ async encryptGroupDistributionParticipants(groupJid, senderKeyId, senderKeyDistributionMessage, participantUserJids) {
369
448
  const distributionPayload = await (0, padding_1.writeRandomPadMax16)(_proto_1.proto.Message.encode({
370
449
  senderKeyDistributionMessage
371
450
  }).finish());
@@ -384,7 +463,7 @@ class WaMessageDispatchCoordinator {
384
463
  fanoutAddresses[index] = address;
385
464
  fanoutTargetsByAddressKey.set((0, jid_2.signalAddressKey)(address), { jid, address });
386
465
  }
387
- const pendingAddresses = await this.senderKeyManager.filterParticipantsNeedingDistribution(groupJid, sender, fanoutAddresses);
466
+ const pendingAddresses = await this.senderKeyManager.filterParticipantsNeedingDistribution(groupJid, senderKeyId, fanoutAddresses);
388
467
  if (pendingAddresses.length === 0) {
389
468
  return {
390
469
  fanoutDeviceJids,
@@ -414,50 +493,82 @@ class WaMessageDispatchCoordinator {
414
493
  for (let index = 0; index < pendingTargets.length; index += 1) {
415
494
  pendingTargetJids[index] = pendingTargets[index].jid;
416
495
  }
496
+ let availableTargets = [];
497
+ let prefetchedAvailableTargets;
417
498
  try {
418
- await this.sessionResolver.ensureSessionsBatch(pendingTargetJids);
499
+ const resolvedTargets = await this.sessionResolver.ensureSessionsBatch(pendingTargetJids);
500
+ availableTargets = resolvedTargets;
501
+ prefetchedAvailableTargets = resolvedTargets;
419
502
  }
420
503
  catch (error) {
504
+ const normalized = (0, primitives_1.toError)(error);
505
+ if (normalized.message === 'identity mismatch') {
506
+ throw normalized;
507
+ }
421
508
  this.logger.warn('group sender-key distribution session sync failed, continuing with available sessions', {
422
509
  groupJid,
423
510
  requested: pendingTargetJids.length,
424
- message: (0, primitives_1.toError)(error).message
511
+ message: normalized.message
425
512
  });
513
+ const pendingTargetAddresses = new Array(pendingTargets.length);
514
+ for (let index = 0; index < pendingTargets.length; index += 1) {
515
+ pendingTargetAddresses[index] = pendingTargets[index].address;
516
+ }
517
+ const hasPendingSessions = await this.signalStore.hasSessions(pendingTargetAddresses);
518
+ const nextAvailableTargets = [];
519
+ for (let index = 0; index < pendingTargets.length; index += 1) {
520
+ if (hasPendingSessions[index]) {
521
+ nextAvailableTargets.push(pendingTargets[index]);
522
+ }
523
+ }
524
+ availableTargets = nextAvailableTargets;
426
525
  }
427
- const hasPendingSessions = await this.signalProtocol.hasSessions(pendingTargets.map((target) => target.address));
428
- const availableTargets = pendingTargets.filter((_target, index) => hasPendingSessions[index]);
429
526
  if (availableTargets.length === 0) {
430
527
  return {
431
528
  fanoutDeviceJids,
432
529
  distributionParticipants: []
433
530
  };
434
531
  }
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
- }));
532
+ const distributionEncryptRequests = new Array(availableTargets.length);
533
+ for (let index = 0; index < availableTargets.length; index += 1) {
534
+ const target = availableTargets[index];
535
+ distributionEncryptRequests[index] = {
536
+ address: target.address,
537
+ plaintext: distributionPayload
538
+ };
539
+ }
540
+ const encryptedDistributionParticipants = await this.signalProtocol.encryptMessagesBatch(distributionEncryptRequests, prefetchedAvailableTargets);
541
+ const distributionParticipants = new Array(availableTargets.length);
542
+ for (let index = 0; index < availableTargets.length; index += 1) {
543
+ const target = availableTargets[index];
544
+ distributionParticipants[index] = {
545
+ jid: target.jid,
546
+ address: target.address,
547
+ encType: encryptedDistributionParticipants[index].type,
548
+ ciphertext: encryptedDistributionParticipants[index].ciphertext
549
+ };
550
+ }
445
551
  return {
446
552
  fanoutDeviceJids,
447
553
  distributionParticipants
448
554
  };
449
555
  }
450
- async publishDirectSignalMessageWithFanout(recipientJid, message, plaintext, type, options) {
556
+ async publishDirectSignalMessageWithFanout(recipientJid, message, plaintext, type, options, edit, mediatype, metaNode) {
451
557
  const sendOptions = await this.withResolvedMessageId(options);
452
558
  const meJid = this.requireCurrentMeJid('sendMessage');
453
559
  const meLid = this.getCurrentMeLid();
454
560
  const selfDeviceJidForRecipient = this.fanoutResolver.resolveSelfDeviceJidForRecipient(recipientJid, meJid, meLid);
455
561
  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
- }));
562
+ const targets = new Array(deviceJids.length);
563
+ for (let index = 0; index < deviceJids.length; index += 1) {
564
+ const jid = deviceJids[index];
565
+ const parsed = (0, jid_1.parseJidFull)(jid);
566
+ targets[index] = {
567
+ jid,
568
+ normalizedJid: parsed.normalizedJid,
569
+ userJid: parsed.userJid
570
+ };
571
+ }
461
572
  const recipientUserJid = (0, jid_1.toUserJid)(recipientJid);
462
573
  const meUserJid = (0, jid_1.toUserJid)(selfDeviceJidForRecipient);
463
574
  this.logger.debug('wa client publish signal fanout', {
@@ -474,30 +585,75 @@ class WaMessageDispatchCoordinator {
474
585
  }
475
586
  }
476
587
  }
477
- await this.sessionResolver.ensureSessionsBatch(deviceJids, expectedIdentityByJid);
478
- const hasSelfDeviceFanout = targets.some((target) => target.userJid === meUserJid);
588
+ const resolvedFanoutTargets = await this.sessionResolver.ensureSessionsBatch(deviceJids, expectedIdentityByJid);
589
+ const resolvedFanoutTargetsByJid = new Map();
590
+ for (let index = 0; index < resolvedFanoutTargets.length; index += 1) {
591
+ const target = resolvedFanoutTargets[index];
592
+ resolvedFanoutTargetsByJid.set((0, jid_1.normalizeDeviceJid)(target.jid), target);
593
+ }
594
+ for (let index = 0; index < targets.length; index += 1) {
595
+ if (!resolvedFanoutTargetsByJid.has(targets[index].normalizedJid)) {
596
+ throw new Error('direct fanout missing signal sessions for one or more targets');
597
+ }
598
+ }
599
+ let hasSelfDeviceFanout = false;
600
+ for (let index = 0; index < targets.length; index += 1) {
601
+ if (targets[index].userJid === meUserJid) {
602
+ hasSelfDeviceFanout = true;
603
+ break;
604
+ }
605
+ }
479
606
  const selfDevicePlaintext = hasSelfDeviceFanout
480
607
  ? await (0, padding_1.writeRandomPadMax16)(_proto_1.proto.Message.encode((0, device_sent_1.wrapDeviceSentMessage)(message, recipientUserJid)).finish())
481
608
  : 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');
609
+ const participantRequests = new Array(targets.length);
610
+ for (let index = 0; index < targets.length; index += 1) {
611
+ const target = targets[index];
612
+ const resolvedTarget = resolvedFanoutTargetsByJid.get(target.normalizedJid);
613
+ if (!resolvedTarget) {
614
+ throw new Error('direct fanout missing signal session for target');
615
+ }
616
+ participantRequests[index] = {
617
+ target,
618
+ address: resolvedTarget.address,
619
+ session: resolvedTarget.session,
620
+ expectedIdentity: target.userJid === recipientUserJid ? sendOptions.expectedIdentity : undefined,
621
+ plaintext: selfDevicePlaintext && target.userJid === meUserJid
622
+ ? selfDevicePlaintext
623
+ : plaintext
624
+ };
625
+ }
626
+ const encryptRequests = new Array(participantRequests.length);
627
+ const prefetchedSessions = new Array(participantRequests.length);
628
+ for (let index = 0; index < participantRequests.length; index += 1) {
629
+ const request = participantRequests[index];
630
+ encryptRequests[index] = {
631
+ address: request.address,
632
+ plaintext: request.plaintext,
633
+ expectedIdentity: request.expectedIdentity
634
+ };
635
+ prefetchedSessions[index] = {
636
+ address: request.address,
637
+ session: request.session
638
+ };
639
+ }
640
+ const encryptedParticipants = await this.signalProtocol.encryptMessagesBatch(encryptRequests, prefetchedSessions);
641
+ const participants = new Array(participantRequests.length);
642
+ for (let index = 0; index < participantRequests.length; index += 1) {
643
+ const request = participantRequests[index];
644
+ participants[index] = {
645
+ jid: request.target.jid,
646
+ encType: encryptedParticipants[index].type,
647
+ ciphertext: encryptedParticipants[index].ciphertext
648
+ };
649
+ }
650
+ let shouldAttachDeviceIdentity = false;
651
+ for (let index = 0; index < participants.length; index += 1) {
652
+ if (participants[index].encType === 'pkmsg') {
653
+ shouldAttachDeviceIdentity = true;
654
+ break;
655
+ }
656
+ }
501
657
  const deviceIdentity = shouldAttachDeviceIdentity
502
658
  ? this.getEncodedSignedDeviceIdentity()
503
659
  : undefined;
@@ -508,13 +664,28 @@ class WaMessageDispatchCoordinator {
508
664
  remoteJid: recipientUserJid,
509
665
  context: 'direct_fanout'
510
666
  });
667
+ let privacyTokenNode;
668
+ try {
669
+ privacyTokenNode =
670
+ (await this.privacyTokenDedup.run(`pt:${recipientUserJid}`, () => this.resolvePrivacyTokenNode(recipientUserJid))) ?? undefined;
671
+ }
672
+ catch (error) {
673
+ this.logger.warn('privacy token resolution failed', {
674
+ to: recipientUserJid,
675
+ message: (0, primitives_1.toError)(error).message
676
+ });
677
+ }
511
678
  const messageNode = (0, message_1.buildDirectMessageFanoutNode)({
512
679
  to: recipientJid,
513
680
  type,
514
681
  id: sendOptions.id,
682
+ edit,
515
683
  participants,
516
684
  deviceIdentity,
517
- reportingNode: reportingArtifacts?.node ?? undefined
685
+ reportingNode: reportingArtifacts?.node ?? undefined,
686
+ privacyTokenNode,
687
+ metaNode,
688
+ mediatype
518
689
  });
519
690
  const replayPayload = {
520
691
  mode: 'plaintext',
@@ -522,12 +693,15 @@ class WaMessageDispatchCoordinator {
522
693
  type,
523
694
  plaintext
524
695
  };
525
- return this.retryTracker.track({
696
+ const result = await this.retryTracker.track({
526
697
  messageIdHint: sendOptions.id ?? messageNode.attrs.id,
527
698
  toJid: recipientJid,
528
699
  type,
529
- replayPayload
700
+ replayPayload,
701
+ eligibleRequesterDeviceJids: deviceJids
530
702
  }, async () => this.messageClient.publishNode(messageNode, sendOptions));
703
+ this.onDirectMessageSent(recipientUserJid);
704
+ return result;
531
705
  }
532
706
  async withResolvedMessageId(options) {
533
707
  const normalizedId = options.id?.trim();
@@ -595,6 +769,25 @@ class WaMessageDispatchCoordinator {
595
769
  }
596
770
  return _proto_1.proto.ADVSignedDeviceIdentity.encode(signedIdentity).finish();
597
771
  }
772
+ resolveUserIcdc(userJid, localIdentity) {
773
+ return this.icdcDedup.run(`icdc:${userJid}:${localIdentity ? '1' : '0'}`, async () => {
774
+ try {
775
+ const snapshots = await this.deviceListStore.getUserDevicesBatch([userJid]);
776
+ const snapshot = snapshots[0];
777
+ if (!snapshot || snapshot.deviceJids.length === 0) {
778
+ return null;
779
+ }
780
+ return (0, icdc_1.resolveIcdcMeta)(snapshot.deviceJids, this.signalStore, snapshot.updatedAtMs, localIdentity);
781
+ }
782
+ catch (error) {
783
+ this.logger.trace('icdc resolution failed', {
784
+ userJid,
785
+ message: (0, primitives_1.toError)(error).message
786
+ });
787
+ return null;
788
+ }
789
+ });
790
+ }
598
791
  requireCurrentMeJid(context) {
599
792
  const meJid = this.getCurrentMeJid();
600
793
  if (meJid) {