zapo-js 0.2.0 → 1.0.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 (863) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +103 -179
  3. package/dist/appstate/{WaAppStateCrypto.js → crypto/WaAppStateCrypto.js} +79 -62
  4. package/dist/appstate/index.js +8 -7
  5. package/dist/appstate/{encoding.js → parsers/encoding.js} +11 -4
  6. package/dist/appstate/{WaAppStateSyncResponseParser.js → parsers/response-parser.js} +20 -8
  7. package/dist/appstate/{WaAppStateSyncClient.js → sync/WaAppStateSyncClient.js} +246 -88
  8. package/dist/appstate/utils.js +16 -0
  9. package/dist/appstate-spec.js +89 -0
  10. package/dist/auth/WaAuthClient.js +117 -13
  11. package/dist/auth/credentials-flow.js +207 -0
  12. package/dist/auth/pairing/WaPairingFlow.js +53 -47
  13. package/dist/auth/pairing/pairing-code-crypto.js +91 -0
  14. package/dist/client/WaClient.js +369 -460
  15. package/dist/client/WaClientFactory.js +377 -93
  16. package/dist/client/connection/WaConnectionManager.js +31 -11
  17. package/dist/client/coordinators/WaAbPropsCoordinator.js +140 -0
  18. package/dist/client/coordinators/WaAppStateMutationCoordinator.js +663 -143
  19. package/dist/client/coordinators/WaBotCoordinator.js +345 -0
  20. package/dist/client/coordinators/WaBroadcastListCoordinator.js +20 -0
  21. package/dist/client/coordinators/WaBusinessCoordinator.js +81 -180
  22. package/dist/client/coordinators/WaEmailCoordinator.js +64 -0
  23. package/dist/client/coordinators/WaGroupCoordinator.js +529 -52
  24. package/dist/client/coordinators/WaIncomingNodeCoordinator.js +130 -20
  25. package/dist/client/coordinators/WaLowLevelCoordinator.js +41 -0
  26. package/dist/client/coordinators/WaMessageCoordinator.js +365 -0
  27. package/dist/client/coordinators/WaMessageDispatchCoordinator.js +724 -216
  28. package/dist/client/coordinators/WaNewsletterCoordinator.js +18 -0
  29. package/dist/client/coordinators/WaOfflineResumeCoordinator.js +114 -0
  30. package/dist/client/coordinators/WaPassiveTasksCoordinator.js +53 -22
  31. package/dist/client/coordinators/WaPresenceCoordinator.js +21 -0
  32. package/dist/client/coordinators/WaPrivacyCoordinator.js +7 -5
  33. package/dist/client/coordinators/WaProfileCoordinator.js +223 -50
  34. package/dist/client/coordinators/WaRetryCoordinator.js +256 -123
  35. package/dist/client/coordinators/WaStatusCoordinator.js +49 -0
  36. package/dist/client/coordinators/WaStreamControlCoordinator.js +6 -6
  37. package/dist/client/coordinators/WaTrustedContactTokenCoordinator.js +29 -10
  38. package/dist/client/events/abprops.js +43 -0
  39. package/dist/client/events/appstate-mutation.js +133 -0
  40. package/dist/client/events/business.js +375 -0
  41. package/dist/client/events/call.js +58 -0
  42. package/dist/client/events/chatstate.js +23 -0
  43. package/dist/client/events/devices.js +15 -16
  44. package/dist/client/{dirty.js → events/dirty.js} +34 -20
  45. package/dist/client/events/group.js +13 -24
  46. package/dist/client/events/identity.js +2 -1
  47. package/dist/client/events/incoming.js +502 -0
  48. package/dist/client/events/mex-notification.js +181 -0
  49. package/dist/client/events/picture.js +33 -0
  50. package/dist/client/events/presence.js +44 -0
  51. package/dist/client/events/privacy-token.js +1 -2
  52. package/dist/client/events/receipt.js +26 -0
  53. package/dist/client/events/registration.js +42 -0
  54. package/dist/client/media.js +400 -0
  55. package/dist/client/messaging/fanout.js +9 -10
  56. package/dist/client/messaging/{participants.js → group-metadata.js} +73 -35
  57. package/dist/client/messaging/ignore-key.js +132 -0
  58. package/dist/client/messaging/key-protocol.js +3 -17
  59. package/dist/client/messaging/link-preview.js +159 -0
  60. package/dist/client/messaging/messages.js +671 -0
  61. package/dist/client/newsletter/admin.js +165 -0
  62. package/dist/client/newsletter/content.js +253 -0
  63. package/dist/client/newsletter/discovery.js +115 -0
  64. package/dist/client/newsletter/messaging.js +197 -0
  65. package/dist/client/newsletter/mex.js +41 -0
  66. package/dist/client/newsletter/parse.js +217 -0
  67. package/dist/client/persistence/WriteBehindPersistence.js +31 -4
  68. package/dist/client/{history-sync.js → persistence/history-sync.js} +125 -18
  69. package/dist/client/persistence/mailbox.js +104 -0
  70. package/dist/client/tokens/cs-token.js +11 -17
  71. package/dist/crypto/core/hkdf.js +12 -12
  72. package/dist/crypto/core/index.js +9 -8
  73. package/dist/crypto/core/keys.js +1 -8
  74. package/dist/crypto/core/nonce.js +12 -12
  75. package/dist/crypto/core/primitives.js +123 -93
  76. package/dist/crypto/core/random.js +9 -9
  77. package/dist/crypto/core/xeddsa.js +59 -0
  78. package/dist/crypto/curves/Ed25519.js +32 -21
  79. package/dist/crypto/curves/X25519.js +71 -17
  80. package/dist/crypto/curves/constants.js +3 -1
  81. package/dist/crypto/math/constants.js +1 -2
  82. package/dist/crypto/math/mod.js +0 -33
  83. package/dist/esm/appstate/{WaAppStateCrypto.js → crypto/WaAppStateCrypto.js} +72 -55
  84. package/dist/esm/appstate/index.js +5 -5
  85. package/dist/esm/appstate/{encoding.js → parsers/encoding.js} +11 -4
  86. package/dist/esm/appstate/{WaAppStateSyncResponseParser.js → parsers/response-parser.js} +20 -8
  87. package/dist/esm/appstate/{WaAppStateSyncClient.js → sync/WaAppStateSyncClient.js} +235 -76
  88. package/dist/esm/appstate/utils.js +16 -0
  89. package/dist/esm/appstate-spec.js +79 -0
  90. package/dist/esm/auth/WaAuthClient.js +114 -10
  91. package/dist/esm/auth/credentials-flow.js +202 -0
  92. package/dist/esm/auth/pairing/WaPairingFlow.js +52 -46
  93. package/dist/esm/auth/pairing/pairing-code-crypto.js +85 -0
  94. package/dist/esm/client/WaClient.js +372 -463
  95. package/dist/esm/client/WaClientFactory.js +380 -96
  96. package/dist/esm/client/connection/WaConnectionManager.js +31 -11
  97. package/dist/esm/client/coordinators/WaAbPropsCoordinator.js +136 -0
  98. package/dist/esm/client/coordinators/WaAppStateMutationCoordinator.js +665 -145
  99. package/dist/esm/client/coordinators/WaBotCoordinator.js +342 -0
  100. package/dist/esm/client/coordinators/WaBroadcastListCoordinator.js +17 -0
  101. package/dist/esm/client/coordinators/WaBusinessCoordinator.js +78 -177
  102. package/dist/esm/client/coordinators/WaEmailCoordinator.js +61 -0
  103. package/dist/esm/client/coordinators/WaGroupCoordinator.js +532 -55
  104. package/dist/esm/client/coordinators/WaIncomingNodeCoordinator.js +132 -22
  105. package/dist/esm/client/coordinators/WaLowLevelCoordinator.js +38 -0
  106. package/dist/esm/client/coordinators/WaMessageCoordinator.js +361 -0
  107. package/dist/esm/client/coordinators/WaMessageDispatchCoordinator.js +719 -211
  108. package/dist/esm/client/coordinators/WaNewsletterCoordinator.js +13 -0
  109. package/dist/esm/client/coordinators/WaOfflineResumeCoordinator.js +110 -0
  110. package/dist/esm/client/coordinators/WaPassiveTasksCoordinator.js +54 -23
  111. package/dist/esm/client/coordinators/WaPresenceCoordinator.js +18 -0
  112. package/dist/esm/client/coordinators/WaPrivacyCoordinator.js +7 -5
  113. package/dist/esm/client/coordinators/WaProfileCoordinator.js +226 -53
  114. package/dist/esm/client/coordinators/WaRetryCoordinator.js +258 -125
  115. package/dist/esm/client/coordinators/WaStatusCoordinator.js +46 -0
  116. package/dist/esm/client/coordinators/WaStreamControlCoordinator.js +6 -6
  117. package/dist/esm/client/coordinators/WaTrustedContactTokenCoordinator.js +31 -12
  118. package/dist/esm/client/events/abprops.js +40 -0
  119. package/dist/esm/client/events/appstate-mutation.js +130 -0
  120. package/dist/esm/client/events/business.js +370 -0
  121. package/dist/esm/client/events/call.js +55 -0
  122. package/dist/esm/client/events/chatstate.js +20 -0
  123. package/dist/esm/client/events/devices.js +15 -16
  124. package/dist/esm/client/{dirty.js → events/dirty.js} +34 -20
  125. package/dist/esm/client/events/group.js +14 -25
  126. package/dist/esm/client/events/identity.js +2 -1
  127. package/dist/esm/client/events/incoming.js +487 -0
  128. package/dist/esm/client/events/mex-notification.js +178 -0
  129. package/dist/esm/client/events/picture.js +30 -0
  130. package/dist/esm/client/events/presence.js +41 -0
  131. package/dist/esm/client/events/privacy-token.js +1 -2
  132. package/dist/esm/client/events/receipt.js +23 -0
  133. package/dist/esm/client/events/registration.js +39 -0
  134. package/dist/esm/client/media.js +384 -0
  135. package/dist/esm/client/messaging/fanout.js +10 -11
  136. package/dist/esm/client/messaging/{participants.js → group-metadata.js} +72 -34
  137. package/dist/esm/client/messaging/ignore-key.js +126 -0
  138. package/dist/esm/client/messaging/key-protocol.js +3 -17
  139. package/dist/esm/client/messaging/link-preview.js +156 -0
  140. package/dist/esm/client/messaging/messages.js +667 -0
  141. package/dist/esm/client/newsletter/admin.js +162 -0
  142. package/dist/esm/client/newsletter/content.js +249 -0
  143. package/dist/esm/client/newsletter/discovery.js +112 -0
  144. package/dist/esm/client/newsletter/messaging.js +194 -0
  145. package/dist/esm/client/newsletter/mex.js +37 -0
  146. package/dist/esm/client/newsletter/parse.js +200 -0
  147. package/dist/esm/client/persistence/WriteBehindPersistence.js +31 -4
  148. package/dist/esm/client/{history-sync.js → persistence/history-sync.js} +124 -18
  149. package/dist/esm/client/persistence/mailbox.js +101 -0
  150. package/dist/esm/client/tokens/cs-token.js +12 -18
  151. package/dist/esm/crypto/core/hkdf.js +14 -14
  152. package/dist/esm/crypto/core/index.js +3 -2
  153. package/dist/esm/crypto/core/keys.js +1 -7
  154. package/dist/esm/crypto/core/nonce.js +11 -11
  155. package/dist/esm/crypto/core/primitives.js +121 -88
  156. package/dist/esm/crypto/core/random.js +8 -7
  157. package/dist/esm/crypto/core/xeddsa.js +55 -0
  158. package/dist/esm/crypto/curves/Ed25519.js +35 -24
  159. package/dist/esm/crypto/curves/X25519.js +74 -20
  160. package/dist/esm/crypto/curves/constants.js +2 -0
  161. package/dist/esm/crypto/math/constants.js +1 -2
  162. package/dist/esm/crypto/math/mod.js +0 -32
  163. package/dist/esm/index.js +7 -2
  164. package/dist/esm/infra/log/ConsoleLogger.js +30 -6
  165. package/dist/esm/infra/log/PinoLogger.js +64 -0
  166. package/dist/esm/infra/log/types.js +4 -2
  167. package/dist/esm/infra/perf/BackgroundQueue.js +55 -13
  168. package/dist/esm/infra/perf/StoreLock.js +7 -4
  169. package/dist/esm/media/constants.js +35 -2
  170. package/dist/esm/media/crypto/WaMediaCrypto.js +374 -0
  171. package/dist/esm/media/index.js +4 -3
  172. package/dist/esm/media/processor.js +1 -0
  173. package/dist/esm/media/sticker/sticker-pack.js +133 -0
  174. package/dist/esm/media/{WaMediaTransferClient.js → transfer/WaMediaTransferClient.js} +84 -196
  175. package/dist/esm/media/{conn.js → transfer/conn.js} +10 -5
  176. package/dist/esm/message/WaMessageClient.js +46 -15
  177. package/dist/esm/message/addons/link-preview/builder.js +36 -0
  178. package/dist/esm/message/addons/link-preview/detect.js +55 -0
  179. package/dist/esm/message/addons/link-preview/fetcher.js +391 -0
  180. package/dist/esm/message/addons/link-preview/types.js +1 -0
  181. package/dist/esm/message/context-info.js +123 -0
  182. package/dist/esm/message/crypto/addon-crypto.js +244 -0
  183. package/dist/esm/message/{icdc.js → crypto/icdc.js} +11 -13
  184. package/dist/esm/message/crypto/phash.js +133 -0
  185. package/dist/esm/message/{reporting-token.js → crypto/reporting-token.js} +7 -7
  186. package/dist/esm/message/{use-case-secret.js → crypto/use-case-secret.js} +21 -4
  187. package/dist/esm/message/{content.js → encode/content.js} +183 -8
  188. package/dist/esm/message/encode/media-payload.js +42 -0
  189. package/dist/esm/message/{padding.js → encode/padding.js} +9 -3
  190. package/dist/esm/message/index.js +2 -2
  191. package/dist/esm/message/kinds/bot.js +111 -0
  192. package/dist/esm/message/kinds/newsletter.js +244 -0
  193. package/dist/esm/message/kinds/sticker-pack.js +29 -0
  194. package/dist/esm/message/{ack.js → primitives/ack.js} +8 -1
  195. package/dist/esm/message/primitives/incoming.js +511 -0
  196. package/dist/esm/message/primitives/peer-data-operation.js +93 -0
  197. package/dist/esm/mex.js +1 -0
  198. package/dist/esm/protocol/abprops.js +169 -0
  199. package/dist/esm/protocol/appstate.js +6 -30
  200. package/dist/esm/protocol/auth.js +3 -2
  201. package/dist/esm/protocol/bot.js +77 -0
  202. package/dist/esm/protocol/browser.js +22 -0
  203. package/dist/esm/protocol/business.js +19 -0
  204. package/dist/esm/protocol/call.js +48 -0
  205. package/dist/esm/protocol/constants.js +10 -2
  206. package/dist/esm/protocol/defaults.js +3 -0
  207. package/dist/esm/protocol/email.js +30 -0
  208. package/dist/esm/protocol/index.js +1 -1
  209. package/dist/esm/protocol/jid.js +142 -11
  210. package/dist/esm/protocol/media.js +25 -12
  211. package/dist/esm/protocol/message.js +4 -1
  212. package/dist/esm/protocol/newsletter.js +61 -0
  213. package/dist/esm/protocol/nodes.js +26 -2
  214. package/dist/esm/protocol/notification.js +24 -2
  215. package/dist/esm/protocol/presence.js +13 -0
  216. package/dist/esm/protocol/status.js +6 -0
  217. package/dist/esm/retry/codec.js +5 -0
  218. package/dist/esm/retry/parse.js +20 -38
  219. package/dist/esm/retry/reason.js +6 -1
  220. package/dist/esm/retry/replay.js +131 -37
  221. package/dist/esm/retry/tracker.js +4 -8
  222. package/dist/esm/signal/api/SignalDeviceSyncApi.js +71 -21
  223. package/dist/esm/signal/api/SignalDigestSyncApi.js +15 -8
  224. package/dist/esm/signal/api/SignalIdentitySyncApi.js +13 -4
  225. package/dist/esm/signal/api/SignalMissingPreKeysSyncApi.js +24 -63
  226. package/dist/esm/signal/api/SignalRotateKeyApi.js +10 -0
  227. package/dist/esm/signal/api/SignalSessionSyncApi.js +23 -51
  228. package/dist/esm/signal/api/codec.js +52 -1
  229. package/dist/esm/signal/api/prekeys.js +4 -0
  230. package/dist/esm/signal/attestation/WaAdvSignature.js +17 -0
  231. package/dist/esm/signal/{crypto → attestation}/constants.js +0 -4
  232. package/dist/esm/signal/constants.js +3 -0
  233. package/dist/esm/signal/encoding.js +6 -332
  234. package/dist/esm/signal/group/SenderKeyChain.js +20 -35
  235. package/dist/esm/signal/group/SenderKeyCodec.js +5 -6
  236. package/dist/esm/signal/group/SenderKeyManager.js +37 -17
  237. package/dist/esm/signal/group/encoding.js +96 -0
  238. package/dist/esm/signal/index.js +4 -1
  239. package/dist/esm/signal/registration/encoding.js +34 -0
  240. package/dist/esm/signal/registration/keygen.js +12 -3
  241. package/dist/esm/signal/registration/utils.js +8 -2
  242. package/dist/esm/signal/session/SignalProtocol.js +129 -26
  243. package/dist/esm/signal/session/SignalRatchet.js +46 -64
  244. package/dist/esm/signal/session/SignalSerializer.js +5 -6
  245. package/dist/esm/signal/session/SignalSession.js +14 -19
  246. package/dist/esm/signal/session/encoding.js +173 -0
  247. package/dist/esm/signal/session/resolver.js +144 -35
  248. package/dist/esm/store/cache/identity.cache.js +75 -0
  249. package/dist/esm/store/cache/privacy-token.cache.js +57 -0
  250. package/dist/esm/store/cache/sender-key.cache.js +101 -0
  251. package/dist/esm/store/cache/session.cache.js +92 -0
  252. package/dist/esm/store/contracts/group-metadata.store.js +1 -0
  253. package/dist/esm/store/contracts/identity.store.js +1 -0
  254. package/dist/esm/store/contracts/message-secret.store.js +1 -0
  255. package/dist/esm/store/contracts/pre-key.store.js +1 -0
  256. package/dist/esm/store/contracts/session.store.js +1 -0
  257. package/dist/esm/store/createStore.js +129 -39
  258. package/dist/esm/store/index.js +15 -10
  259. package/dist/esm/store/locks/contact.lock.js +1 -0
  260. package/dist/esm/store/locks/device-list.lock.js +1 -0
  261. package/dist/esm/store/locks/group-metadata.lock.js +20 -0
  262. package/dist/esm/store/locks/identity.lock.js +16 -0
  263. package/dist/esm/store/locks/message-secret.lock.js +17 -0
  264. package/dist/esm/store/locks/pre-key.lock.js +27 -0
  265. package/dist/esm/store/locks/session.lock.js +19 -0
  266. package/dist/esm/store/locks/signal.lock.js +0 -24
  267. package/dist/esm/store/{providers/memory → memory}/appstate.store.js +5 -5
  268. package/dist/esm/store/memory/auth.store.js +24 -0
  269. package/dist/esm/store/memory/contact.store.js +79 -0
  270. package/dist/esm/store/memory/device-list.store.js +103 -0
  271. package/dist/esm/store/{providers/memory/participants.store.js → memory/group-metadata.store.js} +24 -12
  272. package/dist/esm/store/memory/identity.store.js +31 -0
  273. package/dist/esm/store/memory/message-secret.store.js +90 -0
  274. package/dist/esm/store/{providers/memory → memory}/message.store.js +2 -2
  275. package/dist/esm/store/memory/pre-key.store.js +97 -0
  276. package/dist/esm/store/{providers/memory → memory}/privacy-token.store.js +1 -1
  277. package/dist/esm/store/{providers/memory → memory}/retry.store.js +49 -14
  278. package/dist/esm/store/{providers/memory → memory}/sender-key.store.js +3 -3
  279. package/dist/esm/store/memory/session.store.js +45 -0
  280. package/dist/esm/store/memory/signal.store.js +36 -0
  281. package/dist/esm/store/{providers/memory → memory}/thread.store.js +2 -2
  282. package/dist/esm/store/noop.store.js +26 -4
  283. package/dist/esm/transport/WaComms.js +18 -8
  284. package/dist/esm/transport/WaWebSocket.js +41 -9
  285. package/dist/esm/transport/binary/constants.js +10 -4
  286. package/dist/esm/transport/binary/decoder.js +21 -15
  287. package/dist/esm/transport/binary/encoder.js +96 -21
  288. package/dist/esm/transport/binary/tokens.js +12 -12
  289. package/dist/esm/transport/index.js +7 -0
  290. package/dist/esm/transport/keepalive/WaKeepAlive.js +35 -12
  291. package/dist/esm/transport/node/WaMobileTcpSocket.js +120 -0
  292. package/dist/esm/transport/node/WaNodeOrchestrator.js +26 -13
  293. package/dist/esm/transport/node/WaNodeTransport.js +13 -0
  294. package/dist/esm/transport/node/builders/abprops.js +20 -0
  295. package/dist/esm/transport/node/builders/account-sync.js +7 -15
  296. package/dist/esm/transport/node/builders/bot.js +38 -0
  297. package/dist/esm/transport/node/builders/business.js +30 -30
  298. package/dist/esm/transport/node/builders/chatstate.js +28 -0
  299. package/dist/esm/transport/node/builders/community.js +53 -0
  300. package/dist/esm/transport/node/builders/device.js +11 -0
  301. package/dist/esm/transport/node/builders/email.js +66 -0
  302. package/dist/esm/transport/node/builders/global.js +1 -1
  303. package/dist/esm/transport/node/builders/group.js +114 -4
  304. package/dist/esm/transport/node/builders/media.js +2 -2
  305. package/dist/esm/transport/node/builders/message.js +83 -49
  306. package/dist/esm/transport/node/builders/newsletter.js +176 -0
  307. package/dist/esm/transport/node/builders/offline.js +14 -0
  308. package/dist/esm/transport/node/builders/passive.js +7 -0
  309. package/dist/esm/transport/node/builders/prekeys.js +40 -43
  310. package/dist/esm/transport/node/builders/presence.js +39 -0
  311. package/dist/esm/transport/node/builders/privacy-token.js +19 -23
  312. package/dist/esm/transport/node/builders/privacy.js +6 -6
  313. package/dist/esm/transport/node/builders/profile.js +28 -8
  314. package/dist/esm/transport/node/builders/retry.js +1 -1
  315. package/dist/esm/transport/node/builders/tos.js +58 -0
  316. package/dist/esm/transport/node/builders/usync.js +51 -2
  317. package/dist/esm/transport/node/helpers.js +27 -1
  318. package/dist/esm/transport/node/mex/argo-decoder.js +152 -0
  319. package/dist/esm/transport/node/mex/client.js +105 -0
  320. package/dist/esm/transport/node/query.js +17 -0
  321. package/dist/esm/transport/node/usync.js +12 -0
  322. package/dist/esm/transport/noise/WaClientPayload.js +23 -18
  323. package/dist/esm/transport/noise/WaFrameCodec.js +2 -2
  324. package/dist/esm/transport/noise/WaMobileClientPayload.js +58 -0
  325. package/dist/esm/transport/noise/WaNoiseCert.js +14 -27
  326. package/dist/esm/transport/noise/WaNoiseHandshake.js +27 -25
  327. package/dist/esm/transport/noise/WaNoiseSession.js +48 -67
  328. package/dist/esm/transport/noise/WaNoiseSocket.js +19 -13
  329. package/dist/esm/transport/noise/constants.js +0 -1
  330. package/dist/esm/transport/proxy.js +5 -0
  331. package/dist/esm/transport/stream/parse.js +3 -7
  332. package/dist/esm/transport/wa-web-version-fetcher.js +91 -0
  333. package/dist/esm/util/async.js +4 -0
  334. package/dist/esm/util/bytes.js +37 -2
  335. package/dist/esm/util/clock.js +15 -0
  336. package/dist/esm/util/coercion.js +45 -3
  337. package/dist/esm/util/collections.js +11 -0
  338. package/dist/esm/util/index.js +2 -2
  339. package/dist/esm/util/primitives.js +19 -0
  340. package/dist/esm/util/runtime.js +5 -0
  341. package/dist/esm/version-spec.js +1 -0
  342. package/dist/index.js +31 -1
  343. package/dist/infra/log/ConsoleLogger.js +30 -6
  344. package/dist/infra/log/PinoLogger.js +64 -0
  345. package/dist/infra/log/types.js +4 -2
  346. package/dist/infra/perf/BackgroundQueue.js +55 -13
  347. package/dist/infra/perf/StoreLock.js +7 -4
  348. package/dist/media/constants.js +36 -3
  349. package/dist/media/crypto/WaMediaCrypto.js +378 -0
  350. package/dist/media/index.js +9 -4
  351. package/dist/media/processor.js +2 -0
  352. package/dist/media/sticker/sticker-pack.js +136 -0
  353. package/dist/media/{WaMediaTransferClient.js → transfer/WaMediaTransferClient.js} +87 -229
  354. package/dist/media/{conn.js → transfer/conn.js} +10 -5
  355. package/dist/message/WaMessageClient.js +46 -15
  356. package/dist/message/addons/link-preview/builder.js +39 -0
  357. package/dist/message/addons/link-preview/detect.js +58 -0
  358. package/dist/message/addons/link-preview/fetcher.js +394 -0
  359. package/dist/message/addons/link-preview/types.js +2 -0
  360. package/dist/message/context-info.js +129 -0
  361. package/dist/message/crypto/addon-crypto.js +254 -0
  362. package/dist/message/{icdc.js → crypto/icdc.js} +11 -13
  363. package/dist/message/crypto/phash.js +136 -0
  364. package/dist/message/{reporting-token.js → crypto/reporting-token.js} +7 -7
  365. package/dist/message/{use-case-secret.js → crypto/use-case-secret.js} +21 -4
  366. package/dist/message/{content.js → encode/content.js} +200 -7
  367. package/dist/message/encode/media-payload.js +45 -0
  368. package/dist/message/{padding.js → encode/padding.js} +9 -3
  369. package/dist/message/index.js +2 -2
  370. package/dist/message/kinds/bot.js +120 -0
  371. package/dist/message/kinds/newsletter.js +248 -0
  372. package/dist/message/kinds/sticker-pack.js +34 -0
  373. package/dist/message/{ack.js → primitives/ack.js} +8 -1
  374. package/dist/message/{incoming.js → primitives/incoming.js} +225 -38
  375. package/dist/message/primitives/peer-data-operation.js +96 -0
  376. package/dist/mex.js +6 -0
  377. package/dist/proto.js +1 -1
  378. package/dist/protocol/abprops.js +173 -0
  379. package/dist/protocol/appstate.js +7 -31
  380. package/dist/protocol/auth.js +3 -2
  381. package/dist/protocol/bot.js +81 -0
  382. package/dist/protocol/browser.js +23 -0
  383. package/dist/protocol/business.js +22 -0
  384. package/dist/protocol/call.js +51 -0
  385. package/dist/protocol/constants.js +51 -3
  386. package/dist/protocol/defaults.js +3 -0
  387. package/dist/protocol/email.js +33 -0
  388. package/dist/protocol/index.js +12 -3
  389. package/dist/protocol/jid.js +148 -11
  390. package/dist/protocol/media.js +25 -12
  391. package/dist/protocol/message.js +4 -1
  392. package/dist/protocol/newsletter.js +64 -0
  393. package/dist/protocol/nodes.js +26 -2
  394. package/dist/protocol/notification.js +25 -3
  395. package/dist/protocol/presence.js +16 -0
  396. package/dist/protocol/status.js +9 -0
  397. package/dist/retry/codec.js +5 -0
  398. package/dist/retry/parse.js +16 -34
  399. package/dist/retry/reason.js +6 -1
  400. package/dist/retry/replay.js +129 -35
  401. package/dist/retry/tracker.js +3 -7
  402. package/dist/signal/api/SignalDeviceSyncApi.js +69 -19
  403. package/dist/signal/api/SignalDigestSyncApi.js +14 -7
  404. package/dist/signal/api/SignalIdentitySyncApi.js +13 -4
  405. package/dist/signal/api/SignalMissingPreKeysSyncApi.js +21 -60
  406. package/dist/signal/api/SignalRotateKeyApi.js +10 -0
  407. package/dist/signal/api/SignalSessionSyncApi.js +20 -48
  408. package/dist/signal/api/codec.js +52 -0
  409. package/dist/signal/api/prekeys.js +4 -0
  410. package/dist/signal/attestation/WaAdvSignature.js +26 -0
  411. package/dist/signal/{crypto → attestation}/constants.js +1 -5
  412. package/dist/signal/constants.js +4 -1
  413. package/dist/signal/encoding.js +5 -341
  414. package/dist/signal/group/SenderKeyChain.js +19 -34
  415. package/dist/signal/group/SenderKeyCodec.js +4 -5
  416. package/dist/signal/group/SenderKeyManager.js +36 -16
  417. package/dist/signal/group/encoding.js +101 -0
  418. package/dist/signal/index.js +13 -10
  419. package/dist/signal/registration/encoding.js +39 -0
  420. package/dist/signal/registration/keygen.js +11 -2
  421. package/dist/signal/registration/utils.js +8 -2
  422. package/dist/signal/session/SignalProtocol.js +128 -25
  423. package/dist/signal/session/SignalRatchet.js +41 -60
  424. package/dist/signal/session/SignalSerializer.js +5 -6
  425. package/dist/signal/session/SignalSession.js +13 -19
  426. package/dist/signal/session/encoding.js +183 -0
  427. package/dist/signal/session/resolver.js +144 -35
  428. package/dist/store/cache/identity.cache.js +78 -0
  429. package/dist/store/cache/privacy-token.cache.js +60 -0
  430. package/dist/store/cache/sender-key.cache.js +104 -0
  431. package/dist/store/cache/session.cache.js +95 -0
  432. package/dist/store/contracts/group-metadata.store.js +2 -0
  433. package/dist/store/contracts/identity.store.js +2 -0
  434. package/dist/store/contracts/message-secret.store.js +2 -0
  435. package/dist/store/contracts/pre-key.store.js +2 -0
  436. package/dist/store/contracts/session.store.js +2 -0
  437. package/dist/store/createStore.js +128 -38
  438. package/dist/store/index.js +22 -12
  439. package/dist/store/locks/contact.lock.js +1 -0
  440. package/dist/store/locks/device-list.lock.js +1 -0
  441. package/dist/store/locks/group-metadata.lock.js +23 -0
  442. package/dist/store/locks/identity.lock.js +19 -0
  443. package/dist/store/locks/message-secret.lock.js +20 -0
  444. package/dist/store/locks/pre-key.lock.js +30 -0
  445. package/dist/store/locks/session.lock.js +22 -0
  446. package/dist/store/locks/signal.lock.js +0 -24
  447. package/dist/store/{providers/memory → memory}/appstate.store.js +5 -5
  448. package/dist/store/memory/auth.store.js +28 -0
  449. package/dist/store/memory/contact.store.js +83 -0
  450. package/dist/store/memory/device-list.store.js +107 -0
  451. package/dist/store/{providers/memory/participants.store.js → memory/group-metadata.store.js} +26 -14
  452. package/dist/store/memory/identity.store.js +35 -0
  453. package/dist/store/memory/message-secret.store.js +94 -0
  454. package/dist/store/{providers/memory → memory}/message.store.js +2 -2
  455. package/dist/store/memory/pre-key.store.js +101 -0
  456. package/dist/store/{providers/memory → memory}/privacy-token.store.js +1 -1
  457. package/dist/store/{providers/memory → memory}/retry.store.js +49 -14
  458. package/dist/store/{providers/memory → memory}/sender-key.store.js +3 -3
  459. package/dist/store/memory/session.store.js +49 -0
  460. package/dist/store/memory/signal.store.js +40 -0
  461. package/dist/store/{providers/memory → memory}/thread.store.js +2 -2
  462. package/dist/store/noop.store.js +27 -5
  463. package/dist/transport/WaComms.js +18 -8
  464. package/dist/transport/WaWebSocket.js +41 -9
  465. package/dist/transport/binary/constants.js +11 -5
  466. package/dist/transport/binary/decoder.js +24 -18
  467. package/dist/transport/binary/encoder.js +109 -34
  468. package/dist/transport/binary/tokens.js +12 -12
  469. package/dist/transport/index.js +19 -1
  470. package/dist/transport/keepalive/WaKeepAlive.js +35 -12
  471. package/dist/transport/node/WaMobileTcpSocket.js +124 -0
  472. package/dist/transport/node/WaNodeOrchestrator.js +25 -12
  473. package/dist/transport/node/WaNodeTransport.js +13 -0
  474. package/dist/transport/node/builders/abprops.js +23 -0
  475. package/dist/transport/node/builders/account-sync.js +7 -16
  476. package/dist/transport/node/builders/bot.js +43 -0
  477. package/dist/transport/node/builders/business.js +31 -31
  478. package/dist/transport/node/builders/chatstate.js +31 -0
  479. package/dist/transport/node/builders/community.js +59 -0
  480. package/dist/transport/node/builders/device.js +14 -0
  481. package/dist/transport/node/builders/email.js +73 -0
  482. package/dist/transport/node/builders/global.js +1 -1
  483. package/dist/transport/node/builders/group.js +121 -3
  484. package/dist/transport/node/builders/media.js +1 -1
  485. package/dist/transport/node/builders/message.js +84 -49
  486. package/dist/transport/node/builders/newsletter.js +183 -0
  487. package/dist/transport/node/builders/offline.js +17 -0
  488. package/dist/transport/node/builders/passive.js +10 -0
  489. package/dist/transport/node/builders/prekeys.js +38 -41
  490. package/dist/transport/node/builders/presence.js +43 -0
  491. package/dist/transport/node/builders/privacy-token.js +18 -22
  492. package/dist/transport/node/builders/privacy.js +5 -5
  493. package/dist/transport/node/builders/profile.js +30 -7
  494. package/dist/transport/node/builders/retry.js +1 -1
  495. package/dist/transport/node/builders/tos.js +63 -0
  496. package/dist/transport/node/builders/usync.js +52 -1
  497. package/dist/transport/node/helpers.js +28 -1
  498. package/dist/transport/node/mex/argo-decoder.js +189 -0
  499. package/dist/transport/node/mex/client.js +109 -0
  500. package/dist/transport/node/query.js +17 -0
  501. package/dist/transport/node/usync.js +13 -0
  502. package/dist/transport/noise/WaClientPayload.js +22 -17
  503. package/dist/transport/noise/WaFrameCodec.js +1 -1
  504. package/dist/transport/noise/WaMobileClientPayload.js +61 -0
  505. package/dist/transport/noise/WaNoiseCert.js +13 -26
  506. package/dist/transport/noise/WaNoiseHandshake.js +25 -23
  507. package/dist/transport/noise/WaNoiseSession.js +47 -66
  508. package/dist/transport/noise/WaNoiseSocket.js +18 -12
  509. package/dist/transport/noise/constants.js +1 -2
  510. package/dist/transport/proxy.js +5 -0
  511. package/dist/transport/stream/parse.js +3 -7
  512. package/dist/transport/wa-web-version-fetcher.js +94 -0
  513. package/dist/types/appstate/constants.d.ts +1 -1
  514. package/dist/types/appstate/{WaAppStateCrypto.d.ts → crypto/WaAppStateCrypto.d.ts} +29 -9
  515. package/dist/types/appstate/index.d.ts +5 -5
  516. package/dist/types/appstate/{encoding.d.ts → parsers/encoding.d.ts} +8 -1
  517. package/dist/types/appstate/{WaAppStateSyncResponseParser.d.ts → parsers/response-parser.d.ts} +13 -3
  518. package/dist/types/appstate/sync/WaAppStateSyncClient.d.ts +105 -0
  519. package/dist/types/appstate/types.d.ts +1 -1
  520. package/dist/types/appstate/utils.d.ts +17 -1
  521. package/dist/types/appstate-spec.d.ts +24 -0
  522. package/dist/types/auth/WaAuthClient.d.ts +95 -3
  523. package/dist/types/auth/credentials-flow.d.ts +21 -0
  524. package/dist/types/auth/pairing/WaPairingFlow.d.ts +3 -2
  525. package/dist/types/auth/pairing/{WaPairingCodeCrypto.d.ts → pairing-code-crypto.d.ts} +5 -1
  526. package/dist/types/auth/types.d.ts +88 -1
  527. package/dist/types/client/WaClient.d.ts +183 -65
  528. package/dist/types/client/WaClientFactory.d.ts +40 -9
  529. package/dist/types/client/connection/WaConnectionManager.d.ts +4 -2
  530. package/dist/types/client/connection/WaReceiptQueue.d.ts +1 -1
  531. package/dist/types/client/coordinators/WaAbPropsCoordinator.d.ts +26 -0
  532. package/dist/types/client/coordinators/WaAppStateMutationCoordinator.d.ts +215 -5
  533. package/dist/types/client/coordinators/WaBotCoordinator.d.ts +117 -0
  534. package/dist/types/client/coordinators/WaBroadcastListCoordinator.d.ts +39 -0
  535. package/dist/types/client/coordinators/WaBusinessCoordinator.d.ts +45 -44
  536. package/dist/types/client/coordinators/WaEmailCoordinator.d.ts +40 -0
  537. package/dist/types/client/coordinators/WaGroupCoordinator.d.ts +311 -9
  538. package/dist/types/client/coordinators/WaIncomingNodeCoordinator.d.ts +16 -4
  539. package/dist/types/client/coordinators/WaLowLevelCoordinator.d.ts +47 -0
  540. package/dist/types/client/coordinators/WaMessageCoordinator.d.ts +232 -0
  541. package/dist/types/client/coordinators/WaMessageDispatchCoordinator.d.ts +65 -29
  542. package/dist/types/client/coordinators/WaNewsletterCoordinator.d.ts +13 -0
  543. package/dist/types/client/coordinators/WaOfflineResumeCoordinator.d.ts +31 -0
  544. package/dist/types/client/coordinators/WaPassiveTasksCoordinator.d.ts +15 -3
  545. package/dist/types/client/coordinators/WaPresenceCoordinator.d.ts +27 -0
  546. package/dist/types/client/coordinators/WaPrivacyCoordinator.d.ts +28 -1
  547. package/dist/types/client/coordinators/WaProfileCoordinator.d.ts +117 -2
  548. package/dist/types/client/coordinators/WaRetryCoordinator.d.ts +23 -15
  549. package/dist/types/client/coordinators/WaStatusCoordinator.d.ts +42 -0
  550. package/dist/types/client/coordinators/WaTrustedContactTokenCoordinator.d.ts +16 -2
  551. package/dist/types/client/events/abprops.d.ts +15 -0
  552. package/dist/types/client/events/appstate-mutation.d.ts +3 -0
  553. package/dist/types/client/events/business.d.ts +10 -0
  554. package/dist/types/client/events/call.d.ts +31 -0
  555. package/dist/types/client/events/chatstate.d.ts +9 -0
  556. package/dist/types/client/events/devices.d.ts +5 -4
  557. package/dist/types/client/{dirty.d.ts → events/dirty.d.ts} +7 -4
  558. package/dist/types/client/events/group.d.ts +2 -1
  559. package/dist/types/client/events/identity.d.ts +2 -1
  560. package/dist/types/client/events/incoming.d.ts +65 -0
  561. package/dist/types/client/events/mex-notification.d.ts +6 -0
  562. package/dist/types/client/events/picture.d.ts +8 -0
  563. package/dist/types/client/events/presence.d.ts +28 -0
  564. package/dist/types/client/events/receipt.d.ts +14 -0
  565. package/dist/types/client/events/registration.d.ts +18 -0
  566. package/dist/types/client/index.d.ts +1 -1
  567. package/dist/types/client/media.d.ts +65 -0
  568. package/dist/types/client/messaging/fanout.d.ts +2 -2
  569. package/dist/types/client/messaging/group-metadata.d.ts +19 -0
  570. package/dist/types/client/messaging/ignore-key.d.ts +11 -0
  571. package/dist/types/client/messaging/key-protocol.d.ts +9 -7
  572. package/dist/types/client/messaging/link-preview.d.ts +19 -0
  573. package/dist/types/client/messaging/messages.d.ts +28 -0
  574. package/dist/types/client/newsletter/admin.d.ts +71 -0
  575. package/dist/types/client/newsletter/content.d.ts +42 -0
  576. package/dist/types/client/newsletter/discovery.d.ts +33 -0
  577. package/dist/types/client/newsletter/messaging.d.ts +66 -0
  578. package/dist/types/client/newsletter/mex.d.ts +14 -0
  579. package/dist/types/client/newsletter/parse.d.ts +19 -0
  580. package/dist/types/client/newsletter/types.d.ts +190 -0
  581. package/dist/types/client/persistence/WriteBehindPersistence.d.ts +13 -2
  582. package/dist/types/client/persistence/history-sync.d.ts +29 -0
  583. package/dist/types/client/persistence/mailbox.d.ts +12 -0
  584. package/dist/types/client/tokens/cs-token.d.ts +1 -3
  585. package/dist/types/client/types.d.ts +926 -55
  586. package/dist/types/crypto/core/hkdf.d.ts +10 -2
  587. package/dist/types/crypto/core/index.d.ts +3 -2
  588. package/dist/types/crypto/core/keys.d.ts +0 -4
  589. package/dist/types/crypto/core/nonce.d.ts +4 -5
  590. package/dist/types/crypto/core/primitives.d.ts +31 -20
  591. package/dist/types/crypto/core/random.d.ts +7 -1
  592. package/dist/types/crypto/core/xeddsa.d.ts +11 -0
  593. package/dist/types/crypto/curves/Ed25519.d.ts +7 -1
  594. package/dist/types/crypto/curves/X25519.d.ts +20 -1
  595. package/dist/types/crypto/curves/constants.d.ts +4 -2
  596. package/dist/types/crypto/curves/types.d.ts +0 -5
  597. package/dist/types/crypto/index.d.ts +1 -0
  598. package/dist/types/crypto/math/constants.d.ts +0 -1
  599. package/dist/types/crypto/math/mod.d.ts +0 -1
  600. package/dist/types/index.d.ts +32 -5
  601. package/dist/types/infra/log/ConsoleLogger.d.ts +19 -2
  602. package/dist/types/infra/log/PinoLogger.d.ts +56 -2
  603. package/dist/types/infra/log/types.d.ts +6 -0
  604. package/dist/types/infra/perf/BackgroundQueue.d.ts +19 -0
  605. package/dist/types/infra/perf/StoreLock.d.ts +1 -0
  606. package/dist/types/media/constants.d.ts +9 -2
  607. package/dist/types/media/crypto/WaMediaCrypto.d.ts +59 -0
  608. package/dist/types/media/index.d.ts +7 -4
  609. package/dist/types/media/processor.d.ts +50 -0
  610. package/dist/types/media/sticker/sticker-pack.d.ts +6 -0
  611. package/dist/types/media/{WaMediaTransferClient.d.ts → transfer/WaMediaTransferClient.d.ts} +33 -12
  612. package/dist/types/media/transfer/conn.d.ts +7 -0
  613. package/dist/types/media/types.d.ts +10 -5
  614. package/dist/types/message/WaMessageClient.d.ts +14 -0
  615. package/dist/types/message/addons/link-preview/builder.d.ts +13 -0
  616. package/dist/types/message/addons/link-preview/detect.d.ts +5 -0
  617. package/dist/types/message/addons/link-preview/fetcher.d.ts +13 -0
  618. package/dist/types/message/addons/link-preview/types.d.ts +51 -0
  619. package/dist/types/message/context-info.d.ts +66 -0
  620. package/dist/types/message/crypto/addon-crypto.d.ts +78 -0
  621. package/dist/types/message/{icdc.d.ts → crypto/icdc.d.ts} +6 -6
  622. package/dist/types/message/{phash.d.ts → crypto/phash.d.ts} +1 -1
  623. package/dist/types/message/{reporting-token.d.ts → crypto/reporting-token.d.ts} +2 -2
  624. package/dist/types/message/{use-case-secret.d.ts → crypto/use-case-secret.d.ts} +17 -1
  625. package/dist/types/message/encode/content.d.ts +43 -0
  626. package/dist/types/message/{device-sent.d.ts → encode/device-sent.d.ts} +1 -1
  627. package/dist/types/message/encode/media-payload.d.ts +12 -0
  628. package/dist/types/message/index.d.ts +2 -2
  629. package/dist/types/message/kinds/bot.d.ts +31 -0
  630. package/dist/types/message/kinds/newsletter.d.ts +12 -0
  631. package/dist/types/message/kinds/sticker-pack.d.ts +6 -0
  632. package/dist/types/message/{ack.d.ts → primitives/ack.d.ts} +1 -1
  633. package/dist/types/message/primitives/incoming.d.ts +21 -0
  634. package/dist/types/message/primitives/peer-data-operation.d.ts +23 -0
  635. package/dist/types/message/types.d.ts +218 -28
  636. package/dist/types/mex.d.ts +2 -0
  637. package/dist/types/proto.d.ts +2 -2
  638. package/dist/types/protocol/abprops.d.ts +151 -0
  639. package/dist/types/protocol/appstate.d.ts +4 -49
  640. package/dist/types/protocol/auth.d.ts +2 -2
  641. package/dist/types/protocol/bot.d.ts +45 -0
  642. package/dist/types/protocol/browser.d.ts +9 -0
  643. package/dist/types/protocol/business.d.ts +21 -0
  644. package/dist/types/protocol/call.d.ts +44 -0
  645. package/dist/types/protocol/constants.d.ts +20 -3
  646. package/dist/types/protocol/defaults.d.ts +3 -0
  647. package/dist/types/protocol/email.d.ts +32 -0
  648. package/dist/types/protocol/group.d.ts +1 -1
  649. package/dist/types/protocol/index.d.ts +2 -1
  650. package/dist/types/protocol/jid.d.ts +79 -0
  651. package/dist/types/protocol/media.d.ts +21 -13
  652. package/dist/types/protocol/message.d.ts +4 -0
  653. package/dist/types/protocol/newsletter.d.ts +65 -0
  654. package/dist/types/protocol/nodes.d.ts +24 -0
  655. package/dist/types/protocol/notification.d.ts +22 -0
  656. package/dist/types/protocol/presence.d.ts +16 -0
  657. package/dist/types/protocol/status.d.ts +7 -0
  658. package/dist/types/protocol/stream.d.ts +1 -0
  659. package/dist/types/retry/codec.d.ts +5 -0
  660. package/dist/types/retry/index.d.ts +1 -1
  661. package/dist/types/retry/parse.d.ts +9 -0
  662. package/dist/types/retry/reason.d.ts +6 -1
  663. package/dist/types/retry/replay.d.ts +19 -5
  664. package/dist/types/retry/tracker.d.ts +10 -3
  665. package/dist/types/retry/types.d.ts +3 -8
  666. package/dist/types/signal/api/SignalDeviceSyncApi.d.ts +20 -0
  667. package/dist/types/signal/api/SignalDigestSyncApi.d.ts +13 -0
  668. package/dist/types/signal/api/SignalIdentitySyncApi.d.ts +12 -3
  669. package/dist/types/signal/api/SignalMissingPreKeysSyncApi.d.ts +8 -0
  670. package/dist/types/signal/api/SignalRotateKeyApi.d.ts +10 -0
  671. package/dist/types/signal/api/SignalSessionSyncApi.d.ts +13 -0
  672. package/dist/types/signal/api/codec.d.ts +20 -0
  673. package/dist/types/signal/api/constants.d.ts +1 -1
  674. package/dist/types/signal/api/prekeys.d.ts +4 -0
  675. package/dist/types/signal/{crypto → attestation}/WaAdvSignature.d.ts +2 -4
  676. package/dist/types/signal/attestation/constants.d.ts +4 -0
  677. package/dist/types/signal/constants.d.ts +7 -4
  678. package/dist/types/signal/encoding.d.ts +6 -62
  679. package/dist/types/signal/group/SenderKeyChain.d.ts +2 -2
  680. package/dist/types/signal/group/SenderKeyManager.d.ts +24 -2
  681. package/dist/types/signal/group/encoding.d.ts +25 -0
  682. package/dist/types/signal/index.d.ts +4 -1
  683. package/dist/types/signal/registration/encoding.d.ts +30 -0
  684. package/dist/types/signal/registration/keygen.d.ts +10 -0
  685. package/dist/types/signal/registration/utils.d.ts +7 -1
  686. package/dist/types/signal/session/SignalProtocol.d.ts +66 -2
  687. package/dist/types/signal/session/SignalRatchet.d.ts +2 -3
  688. package/dist/types/signal/session/SignalSerializer.d.ts +2 -1
  689. package/dist/types/signal/session/SignalSession.d.ts +0 -1
  690. package/dist/types/signal/session/encoding.d.ts +28 -0
  691. package/dist/types/signal/session/resolver.d.ts +18 -2
  692. package/dist/types/signal/types.d.ts +16 -4
  693. package/dist/types/store/cache/identity.cache.d.ts +15 -0
  694. package/dist/types/store/cache/privacy-token.cache.d.ts +15 -0
  695. package/dist/types/store/cache/sender-key.cache.d.ts +18 -0
  696. package/dist/types/store/cache/session.cache.d.ts +23 -0
  697. package/dist/types/store/contracts/contact.store.d.ts +14 -0
  698. package/dist/types/store/contracts/device-list.store.d.ts +13 -0
  699. package/dist/types/store/contracts/group-metadata.store.d.ts +14 -0
  700. package/dist/types/store/contracts/identity.store.d.ts +11 -0
  701. package/dist/types/store/contracts/message-secret.store.d.ts +16 -0
  702. package/dist/types/store/contracts/message.store.d.ts +0 -2
  703. package/dist/types/store/contracts/pre-key.store.d.ts +13 -0
  704. package/dist/types/store/contracts/session.store.d.ts +14 -0
  705. package/dist/types/store/contracts/signal.store.d.ts +1 -34
  706. package/dist/types/store/createStore.d.ts +54 -2
  707. package/dist/types/store/index.d.ts +22 -13
  708. package/dist/types/store/locks/group-metadata.lock.d.ts +2 -0
  709. package/dist/types/store/locks/identity.lock.d.ts +3 -0
  710. package/dist/types/store/locks/message-secret.lock.d.ts +3 -0
  711. package/dist/types/store/locks/pre-key.lock.d.ts +3 -0
  712. package/dist/types/store/locks/session.lock.d.ts +3 -0
  713. package/dist/types/store/{providers/memory → memory}/appstate.store.d.ts +2 -2
  714. package/dist/types/store/memory/auth.store.d.ts +18 -0
  715. package/dist/types/store/{providers/memory → memory}/contact.store.d.ts +6 -1
  716. package/dist/types/store/{providers/memory → memory}/device-list.store.d.ts +15 -2
  717. package/dist/types/store/memory/group-metadata.store.d.ts +27 -0
  718. package/dist/types/store/memory/identity.store.d.ts +18 -0
  719. package/dist/types/store/memory/message-secret.store.d.ts +31 -0
  720. package/dist/types/store/{providers/memory → memory}/message.store.d.ts +1 -1
  721. package/dist/types/store/memory/pre-key.store.d.ts +23 -0
  722. package/dist/types/store/{providers/memory → memory}/privacy-token.store.d.ts +1 -1
  723. package/dist/types/store/{providers/memory → memory}/retry.store.d.ts +23 -4
  724. package/dist/types/store/{providers/memory → memory}/sender-key.store.d.ts +2 -2
  725. package/dist/types/store/memory/session.store.d.ts +21 -0
  726. package/dist/types/store/memory/signal.store.d.ts +16 -0
  727. package/dist/types/store/{providers/memory → memory}/thread.store.d.ts +1 -1
  728. package/dist/types/store/noop.store.d.ts +6 -2
  729. package/dist/types/store/types.d.ts +271 -7
  730. package/dist/types/transport/WaComms.d.ts +5 -0
  731. package/dist/types/transport/WaWebSocket.d.ts +6 -0
  732. package/dist/types/transport/binary/constants.d.ts +8 -2
  733. package/dist/types/transport/binary/decoder.d.ts +5 -0
  734. package/dist/types/transport/binary/encoder.d.ts +5 -0
  735. package/dist/types/transport/binary/tokens.d.ts +6 -6
  736. package/dist/types/transport/index.d.ts +9 -0
  737. package/dist/types/transport/keepalive/WaKeepAlive.d.ts +11 -1
  738. package/dist/types/transport/node/WaMobileTcpSocket.d.ts +24 -0
  739. package/dist/types/transport/node/WaNodeOrchestrator.d.ts +11 -2
  740. package/dist/types/transport/node/WaNodeTransport.d.ts +13 -0
  741. package/dist/types/transport/node/builders/abprops.d.ts +5 -0
  742. package/dist/types/transport/node/builders/account-sync.d.ts +1 -2
  743. package/dist/types/transport/node/builders/bot.d.ts +4 -0
  744. package/dist/types/transport/node/builders/business.d.ts +21 -4
  745. package/dist/types/transport/node/builders/chatstate.d.ts +11 -0
  746. package/dist/types/transport/node/builders/community.d.ts +17 -0
  747. package/dist/types/transport/node/builders/device.d.ts +2 -0
  748. package/dist/types/transport/node/builders/email.d.ts +11 -0
  749. package/dist/types/transport/node/builders/group.d.ts +44 -2
  750. package/dist/types/transport/node/builders/message.d.ts +11 -6
  751. package/dist/types/transport/node/builders/newsletter.d.ts +73 -0
  752. package/dist/types/transport/node/builders/offline.d.ts +2 -0
  753. package/dist/types/transport/node/builders/passive.d.ts +3 -0
  754. package/dist/types/transport/node/builders/prekeys.d.ts +4 -3
  755. package/dist/types/transport/node/builders/presence.d.ts +13 -0
  756. package/dist/types/transport/node/builders/profile.d.ts +3 -0
  757. package/dist/types/transport/node/builders/tos.d.ts +12 -0
  758. package/dist/types/transport/node/builders/usync.d.ts +16 -0
  759. package/dist/types/transport/node/helpers.d.ts +3 -1
  760. package/dist/types/transport/node/mex/argo-decoder.d.ts +11 -0
  761. package/dist/types/transport/node/mex/client.d.ts +29 -0
  762. package/dist/types/transport/node/query.d.ts +19 -1
  763. package/dist/types/transport/node/usync.d.ts +3 -0
  764. package/dist/types/transport/noise/WaMobileClientPayload.d.ts +34 -0
  765. package/dist/types/transport/noise/WaNoiseCert.d.ts +12 -1
  766. package/dist/types/transport/noise/WaNoiseHandshake.d.ts +12 -6
  767. package/dist/types/transport/noise/WaNoiseSession.d.ts +1 -1
  768. package/dist/types/transport/noise/WaNoiseSocket.d.ts +12 -6
  769. package/dist/types/transport/noise/constants.d.ts +4 -5
  770. package/dist/types/transport/proxy.d.ts +5 -0
  771. package/dist/types/transport/types.d.ts +15 -0
  772. package/dist/types/transport/wa-web-version-fetcher.d.ts +44 -0
  773. package/dist/types/util/async.d.ts +4 -0
  774. package/dist/types/util/bytes.d.ts +36 -1
  775. package/dist/types/util/clock.d.ts +6 -0
  776. package/dist/types/util/coercion.d.ts +25 -0
  777. package/dist/types/util/collections.d.ts +8 -0
  778. package/dist/types/util/index.d.ts +2 -2
  779. package/dist/types/util/primitives.d.ts +11 -0
  780. package/dist/types/util/runtime.d.ts +5 -0
  781. package/dist/types/version-spec.d.ts +1 -0
  782. package/dist/util/async.js +4 -0
  783. package/dist/util/bytes.js +37 -2
  784. package/dist/util/clock.js +18 -0
  785. package/dist/util/coercion.js +48 -3
  786. package/dist/util/collections.js +12 -0
  787. package/dist/util/index.js +7 -1
  788. package/dist/util/primitives.js +20 -0
  789. package/dist/util/runtime.js +5 -0
  790. package/dist/version-spec.js +5 -0
  791. package/package.json +37 -11
  792. package/spec/appstate/index.d.ts +188 -0
  793. package/spec/appstate/index.js +850 -0
  794. package/spec/mex/index.d.ts +4172 -0
  795. package/spec/mex/index.js +261 -0
  796. package/spec/proto/index.d.ts +16305 -0
  797. package/spec/proto/index.js +1 -0
  798. package/spec/version/index.d.ts +4 -0
  799. package/spec/version/index.js +9 -0
  800. package/spec/version/version.json +3 -0
  801. package/dist/auth/flow/WaAuthCredentialsFlow.js +0 -130
  802. package/dist/auth/pairing/WaPairingCodeCrypto.js +0 -77
  803. package/dist/auth/pairing/constants.js +0 -5
  804. package/dist/client/connection/WaKeyShareCoordinator.js +0 -63
  805. package/dist/client/events/chat.js +0 -227
  806. package/dist/client/incoming.js +0 -269
  807. package/dist/client/mailbox.js +0 -50
  808. package/dist/client/messages.js +0 -228
  809. package/dist/esm/auth/flow/WaAuthCredentialsFlow.js +0 -125
  810. package/dist/esm/auth/pairing/WaPairingCodeCrypto.js +0 -73
  811. package/dist/esm/auth/pairing/constants.js +0 -2
  812. package/dist/esm/client/connection/WaKeyShareCoordinator.js +0 -59
  813. package/dist/esm/client/events/chat.js +0 -224
  814. package/dist/esm/client/incoming.js +0 -260
  815. package/dist/esm/client/mailbox.js +0 -47
  816. package/dist/esm/client/messages.js +0 -224
  817. package/dist/esm/media/WaMediaCrypto.js +0 -304
  818. package/dist/esm/message/addon-crypto.js +0 -59
  819. package/dist/esm/message/incoming.js +0 -325
  820. package/dist/esm/message/phash.js +0 -27
  821. package/dist/esm/signal/crypto/WaAdvSignature.js +0 -64
  822. package/dist/esm/store/locks/participants.lock.js +0 -20
  823. package/dist/esm/store/providers/memory/contact.store.js +0 -28
  824. package/dist/esm/store/providers/memory/device-list.store.js +0 -64
  825. package/dist/esm/store/providers/memory/signal.store.js +0 -199
  826. package/dist/esm/transport/node/builders/index.js +0 -11
  827. package/dist/media/WaMediaCrypto.js +0 -308
  828. package/dist/message/addon-crypto.js +0 -65
  829. package/dist/message/phash.js +0 -30
  830. package/dist/signal/crypto/WaAdvSignature.js +0 -76
  831. package/dist/store/locks/participants.lock.js +0 -23
  832. package/dist/store/providers/memory/contact.store.js +0 -32
  833. package/dist/store/providers/memory/device-list.store.js +0 -68
  834. package/dist/store/providers/memory/signal.store.js +0 -203
  835. package/dist/transport/node/builders/index.js +0 -51
  836. package/dist/types/appstate/WaAppStateSyncClient.d.ts +0 -66
  837. package/dist/types/auth/flow/WaAuthCredentialsFlow.d.ts +0 -14
  838. package/dist/types/auth/pairing/constants.d.ts +0 -2
  839. package/dist/types/client/connection/WaKeyShareCoordinator.d.ts +0 -14
  840. package/dist/types/client/events/chat.d.ts +0 -3
  841. package/dist/types/client/history-sync.d.ts +0 -20
  842. package/dist/types/client/incoming.d.ts +0 -37
  843. package/dist/types/client/mailbox.d.ts +0 -10
  844. package/dist/types/client/messages.d.ts +0 -16
  845. package/dist/types/client/messaging/participants.d.ts +0 -13
  846. package/dist/types/media/WaMediaCrypto.d.ts +0 -13
  847. package/dist/types/media/conn.d.ts +0 -3
  848. package/dist/types/message/addon-crypto.d.ts +0 -25
  849. package/dist/types/message/content.d.ts +0 -12
  850. package/dist/types/message/incoming.d.ts +0 -18
  851. package/dist/types/signal/crypto/constants.d.ts +0 -5
  852. package/dist/types/store/contracts/participants.store.d.ts +0 -13
  853. package/dist/types/store/locks/participants.lock.d.ts +0 -2
  854. package/dist/types/store/providers/memory/participants.store.d.ts +0 -17
  855. package/dist/types/store/providers/memory/signal.store.d.ts +0 -58
  856. package/dist/types/transport/node/builders/index.d.ts +0 -11
  857. package/proto/index.d.ts +0 -10903
  858. package/proto/index.js +0 -1
  859. /package/dist/{store/contracts/participants.store.js → client/newsletter/types.js} +0 -0
  860. /package/dist/esm/{store/contracts/participants.store.js → client/newsletter/types.js} +0 -0
  861. /package/dist/esm/message/{device-sent.js → encode/device-sent.js} +0 -0
  862. /package/dist/message/{device-sent.js → encode/device-sent.js} +0 -0
  863. /package/dist/types/message/{padding.d.ts → encode/padding.d.ts} +0 -0
@@ -2,67 +2,51 @@
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");
5
6
  const PromiseDedup_1 = require("../../infra/perf/PromiseDedup");
6
7
  const _message_1 = require("../../message/index.js");
7
- const content_1 = require("../../message/content");
8
- const device_sent_1 = require("../../message/device-sent");
9
- const icdc_1 = require("../../message/icdc");
10
- const padding_1 = require("../../message/padding");
11
- const phash_1 = require("../../message/phash");
12
- const reporting_token_1 = require("../../message/reporting-token");
8
+ const context_info_1 = require("../../message/context-info");
9
+ const icdc_1 = require("../../message/crypto/icdc");
10
+ const phash_1 = require("../../message/crypto/phash");
11
+ const reporting_token_1 = require("../../message/crypto/reporting-token");
12
+ const content_1 = require("../../message/encode/content");
13
+ const device_sent_1 = require("../../message/encode/device-sent");
14
+ const padding_1 = require("../../message/encode/padding");
15
+ const bot_1 = require("../../message/kinds/bot");
13
16
  const _proto_1 = require("../../proto.js");
14
17
  const constants_1 = require("../../protocol/constants");
15
18
  const jid_1 = require("../../protocol/jid");
16
- const jid_2 = require("../../protocol/jid");
17
19
  const binary_1 = require("../../transport/binary");
18
20
  const message_1 = require("../../transport/node/builders/message");
19
21
  const bytes_1 = require("../../util/bytes");
20
- const primitives_1 = require("../../util/primitives");
22
+ const primitives_2 = require("../../util/primitives");
21
23
  class WaMessageDispatchCoordinator {
22
24
  constructor(options) {
23
25
  this.icdcDedup = new PromiseDedup_1.PromiseDedup();
24
26
  this.privacyTokenDedup = new PromiseDedup_1.PromiseDedup();
25
27
  this.distributionDedup = new PromiseDedup_1.PromiseDedup();
26
- this.logger = options.logger;
27
- this.messageClient = options.messageClient;
28
- this.retryTracker = options.retryTracker;
29
- this.sessionResolver = options.sessionResolver;
30
- this.fanoutResolver = options.fanoutResolver;
31
- this.participantsCache = options.participantsCache;
32
- this.appStateSyncKeyProtocol = options.appStateSyncKeyProtocol;
33
- this.buildMessageContent = options.buildMessageContent;
34
- this.senderKeyManager = options.senderKeyManager;
35
- this.signalProtocol = options.signalProtocol;
36
- this.signalStore = options.signalStore;
37
- this.deviceListStore = options.deviceListStore;
38
- this.getCurrentMeJid = options.getCurrentMeJid;
39
- this.getCurrentMeLid = options.getCurrentMeLid;
40
- this.getCurrentSignedIdentity = options.getCurrentSignedIdentity;
41
- this.resolvePrivacyTokenNode = options.resolvePrivacyTokenNode;
42
- this.onDirectMessageSent = options.onDirectMessageSent;
28
+ this.deps = options;
29
+ this.mobileMessageIdFormat = options.mobileMessageIdFormat ?? false;
30
+ this.serverClock = options.serverClock;
43
31
  }
44
32
  async publishMessageNode(node, options = {}) {
45
- this.logger.debug('wa client publish message node', {
33
+ this.deps.logger.trace('wa client publish message node', {
46
34
  tag: node.tag,
47
35
  type: node.attrs.type,
48
36
  to: node.attrs.to
49
37
  });
50
- const messageType = node.attrs.type ?? 'text';
51
38
  const replayPayload = {
52
39
  mode: 'opaque_node',
53
40
  node: (0, binary_1.encodeBinaryNode)(node)
54
41
  };
55
- return this.retryTracker.track({
42
+ return this.deps.retryTracker.track({
56
43
  messageIdHint: node.attrs.id,
57
44
  toJid: node.attrs.to,
58
- type: messageType,
59
- replayPayload,
60
- participantJid: node.attrs.participant,
61
- recipientJid: node.attrs.recipient
62
- }, async () => this.messageClient.publishNode(node, options));
45
+ replayPayload
46
+ }, async () => this.deps.messageClient.publishNode(node, options));
63
47
  }
64
48
  async publishEncryptedMessage(input, options = {}) {
65
- this.logger.debug('wa client publish encrypted message', {
49
+ this.deps.logger.trace('wa client publish encrypted message', {
66
50
  to: input.to,
67
51
  type: input.type,
68
52
  encType: input.encType
@@ -75,14 +59,12 @@ class WaMessageDispatchCoordinator {
75
59
  ciphertext: input.ciphertext,
76
60
  participant: input.participant
77
61
  };
78
- return this.retryTracker.track({
62
+ return this.deps.retryTracker.track({
79
63
  messageIdHint: input.id,
80
64
  toJid: input.to,
81
- type: input.type ?? 'text',
82
65
  replayPayload,
83
- participantJid: input.participant,
84
66
  eligibleRequesterDeviceJids: [input.to]
85
- }, async () => this.messageClient.publishEncrypted(input, options));
67
+ }, async () => this.deps.messageClient.publishEncrypted(input, options));
86
68
  }
87
69
  async publishSignalMessage(input, options = {}) {
88
70
  this.requireCurrentMeJid('publishSignalMessage');
@@ -90,30 +72,29 @@ class WaMessageDispatchCoordinator {
90
72
  if (address.server === constants_1.WA_DEFAULTS.GROUP_SERVER) {
91
73
  throw new Error('publishSignalMessage currently supports only direct chats; use sender-key flow for groups');
92
74
  }
93
- this.logger.debug('wa client publish signal message', {
75
+ this.deps.logger.trace('wa client publish signal message', {
94
76
  to: input.to,
95
77
  type: input.type
96
78
  });
97
79
  const [paddedPlaintext] = await Promise.all([
98
80
  (0, padding_1.writeRandomPadMax16)(input.plaintext),
99
- this.sessionResolver.ensureSession(address, input.to, input.expectedIdentity)
81
+ this.deps.sessionResolver.ensureSession(address, input.to, input.expectedIdentity)
100
82
  ]);
101
- const encrypted = await this.signalProtocol.encryptMessage(address, paddedPlaintext, input.expectedIdentity);
83
+ const encrypted = await this.deps.signalProtocol.encryptMessage(address, paddedPlaintext, input.expectedIdentity);
102
84
  const messageType = input.type ?? 'text';
85
+ const deviceIdentity = encrypted.type === 'pkmsg' ? this.getEncodedSignedDeviceIdentity() : undefined;
103
86
  const replayPayload = {
104
87
  mode: 'plaintext',
105
88
  to: input.to,
106
89
  type: messageType,
107
90
  plaintext: paddedPlaintext
108
91
  };
109
- return this.retryTracker.track({
92
+ return this.deps.retryTracker.track({
110
93
  messageIdHint: input.id,
111
94
  toJid: input.to,
112
- type: messageType,
113
95
  replayPayload,
114
- participantJid: input.participant,
115
96
  eligibleRequesterDeviceJids: [input.to]
116
- }, async () => this.messageClient.publishEncrypted({
97
+ }, async () => this.deps.messageClient.publishEncrypted({
117
98
  to: input.to,
118
99
  encType: encrypted.type,
119
100
  ciphertext: encrypted.ciphertext,
@@ -122,18 +103,130 @@ class WaMessageDispatchCoordinator {
122
103
  category: input.category,
123
104
  pushPriority: input.pushPriority,
124
105
  participant: input.participant,
125
- deviceFanout: input.deviceFanout
106
+ deviceFanout: input.deviceFanout,
107
+ deviceIdentity,
108
+ metaNode: input.metaNode
126
109
  }, options));
127
110
  }
128
111
  async sendMessage(to, content, options = {}) {
129
112
  const recipientJid = (0, jid_1.normalizeRecipientJid)(to);
130
- const [message, sendOptions] = await Promise.all([
131
- this.buildMessageContent(content),
132
- this.withResolvedMessageId(options)
133
- ]);
134
- const messageWithSecret = await (0, _message_1.ensureMessageSecret)(message);
135
- const meJid = this.getCurrentMeJid();
136
- const regInfo = meJid ? await this.signalStore.getRegistrationInfo() : null;
113
+ if ((0, jid_1.isNewsletterJid)(recipientJid)) {
114
+ if (!this.deps.sendNewsletterMessage) {
115
+ throw new Error('newsletter sendMessage requires sendNewsletterMessage dependency');
116
+ }
117
+ const newsletterCtx = (0, context_info_1.resolveSendContextInfo)({
118
+ contentLevel: pickContentContextInfo(content),
119
+ optionsLevel: options.contextInfo,
120
+ quote: options.quote,
121
+ forward: options.forward,
122
+ mentions: options.mentions
123
+ });
124
+ assertNewsletterContextInfoCompatible(newsletterCtx);
125
+ const sendOptions = await this.withResolvedMessageId(options);
126
+ return this.deps.sendNewsletterMessage(recipientJid, content, sendOptions, newsletterCtx);
127
+ }
128
+ let built;
129
+ let sendOptions;
130
+ if ((0, content_1.isSendAddonCryptoMessage)(content)) {
131
+ sendOptions = await this.withResolvedMessageId(options);
132
+ const meJid = this.deps.getCurrentCredentials()?.meJid;
133
+ if (!meJid) {
134
+ throw new Error(`${content.type} sendMessage requires registered meJid`);
135
+ }
136
+ built = await this.deps.buildMessageContent(content, {
137
+ to: recipientJid,
138
+ outgoingStanzaId: sendOptions.id,
139
+ meJid: (0, jid_1.toUserJid)(meJid)
140
+ });
141
+ }
142
+ else {
143
+ ;
144
+ [built, sendOptions] = await Promise.all([
145
+ this.deps.buildMessageContent(content, { to: recipientJid }),
146
+ this.withResolvedMessageId(options)
147
+ ]);
148
+ }
149
+ let optionsCtx = options.contextInfo;
150
+ if (options.expirationSeconds !== undefined) {
151
+ optionsCtx = { ...optionsCtx, expirationSeconds: options.expirationSeconds };
152
+ }
153
+ if ((0, jid_1.isGroupJid)(recipientJid) &&
154
+ optionsCtx?.expirationSeconds === undefined &&
155
+ !options.disableGroupEphemeralAutoInject) {
156
+ const cachedEphemeral = await this.deps.groupMetadataCache.resolveEphemeral(recipientJid);
157
+ if (cachedEphemeral !== null && cachedEphemeral > 0) {
158
+ optionsCtx = { ...optionsCtx, expirationSeconds: cachedEphemeral };
159
+ }
160
+ }
161
+ const ctx = (0, context_info_1.resolveSendContextInfo)({
162
+ contentLevel: pickContentContextInfo(content),
163
+ optionsLevel: optionsCtx,
164
+ quote: options.quote,
165
+ forward: options.forward,
166
+ mentions: options.mentions,
167
+ meLid: this.deps.getCurrentCredentials()?.meLid
168
+ });
169
+ const withCtx = ctx ? (0, context_info_1.applyContextInfo)(built.message, ctx) : built.message;
170
+ const withViewOnce = options.viewOnce ? (0, content_1.wrapAsViewOnce)(withCtx) : withCtx;
171
+ const editKey = options.editKey;
172
+ let editId;
173
+ let editParticipant;
174
+ let editTimestamp;
175
+ if (editKey) {
176
+ if ('rawNode' in editKey) {
177
+ editId = editKey.key?.id ?? undefined;
178
+ editParticipant = editKey.key?.participant ?? undefined;
179
+ }
180
+ else {
181
+ editId = editKey.id;
182
+ editParticipant = editKey.participant;
183
+ editTimestamp = 'timestampMs' in editKey ? editKey.timestampMs : undefined;
184
+ }
185
+ }
186
+ const message = editKey
187
+ ? {
188
+ protocolMessage: {
189
+ type: _proto_1.proto.Message.ProtocolMessage.Type.MESSAGE_EDIT,
190
+ key: {
191
+ remoteJid: recipientJid,
192
+ fromMe: true,
193
+ id: editId,
194
+ ...(editParticipant ? { participant: editParticipant } : {})
195
+ },
196
+ editedMessage: withViewOnce,
197
+ timestampMs: editTimestamp ?? this.serverClock.nowMs()
198
+ }
199
+ }
200
+ : withViewOnce;
201
+ const upload = built.upload;
202
+ const messageWithOverride = options.messageSecret
203
+ ? {
204
+ ...message,
205
+ messageContextInfo: {
206
+ ...(message.messageContextInfo ?? {}),
207
+ messageSecret: (0, _message_1.assertMessageSecret)(options.messageSecret, 'options.messageSecret')
208
+ }
209
+ }
210
+ : message;
211
+ const messageWithSecret = await (0, _message_1.ensureMessageSecret)(messageWithOverride);
212
+ const rawSecret = messageWithSecret.messageContextInfo?.messageSecret;
213
+ if (rawSecret &&
214
+ rawSecret.length > 0 &&
215
+ sendOptions.id &&
216
+ (0, content_1.needsSecretPersistence)(messageWithSecret)) {
217
+ const meJid = this.deps.getCurrentCredentials()?.meJid ?? '';
218
+ void this.deps.messageSecretStore
219
+ .set(sendOptions.id, { secret: rawSecret, senderJid: meJid })
220
+ .catch((error) => {
221
+ this.deps.logger.warn('failed to persist outgoing message secret', {
222
+ id: sendOptions.id,
223
+ to: recipientJid,
224
+ message: (0, primitives_2.toError)(error).message
225
+ });
226
+ });
227
+ }
228
+ const meJid = this.deps.getCurrentCredentials()?.meJid;
229
+ const regInfo = meJid ? await this.deps.signalStore.getRegistrationInfo() : null;
137
230
  const localPubKey = regInfo?.identityKeyPair.pubKey;
138
231
  const meParsed = meJid ? (0, jid_1.parseJidFull)(meJid) : undefined;
139
232
  const meUserJid = meParsed?.userJid;
@@ -145,67 +238,343 @@ class WaMessageDispatchCoordinator {
145
238
  ]);
146
239
  const messageWithIcdc = (0, icdc_1.injectDeviceListMetadata)(messageWithSecret, senderIcdc, recipientIcdc);
147
240
  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;
241
+ const buttonAddonKind = (0, content_1.resolveButtonAddonKind)(messageWithIcdc);
242
+ const buttonAddonNode = buttonAddonKind ? (0, message_1.buildButtonAddonNode)(buttonAddonKind) : undefined;
243
+ // when a <biz> companion is attached the stanza must advertise type=text and
244
+ // omit enc.mediatype; sending type=media + mediatype=list/button alongside the
245
+ // companion is rejected by the server as SMAX_INVALID (479).
246
+ const type = buttonAddonKind ? 'text' : (0, content_1.resolveMessageTypeAttr)(messageWithIcdc);
247
+ const edit = (0, content_1.resolveEditAttr)(messageWithIcdc) ?? undefined;
248
+ const mediatype = buttonAddonKind
249
+ ? undefined
250
+ : ((0, content_1.resolveEncMediaType)(messageWithIcdc) ?? undefined);
151
251
  const metaAttrs = (0, content_1.resolveMetaAttrs)(messageWithIcdc);
152
252
  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);
253
+ const customNodes = [];
254
+ if (metaNode)
255
+ customNodes.push(metaNode);
256
+ if (buttonAddonNode)
257
+ customNodes.push(buttonAddonNode);
258
+ if (options.customNodes) {
259
+ for (const node of options.customNodes) {
260
+ customNodes.push(node);
156
261
  }
157
- return this.publishGroupSenderKeyMessage(recipientJid, messageWithIcdc, plaintext, type, sendOptions, {}, edit, mediatype, metaNode);
158
262
  }
159
- const directRecipientJid = (0, jid_1.toUserJid)(recipientJid);
160
- return this.publishDirectSignalMessageWithFanout(directRecipientJid, messageWithIcdc, plaintext, type, sendOptions, edit, mediatype, metaNode);
263
+ const decryptFail = (0, content_1.resolveDecryptFailAttr)(messageWithIcdc);
264
+ const envelope = {
265
+ message: messageWithIcdc,
266
+ plaintext,
267
+ type,
268
+ edit,
269
+ mediatype,
270
+ decryptFail,
271
+ customNodes: customNodes.length > 0 ? customNodes : undefined,
272
+ sendOptions
273
+ };
274
+ const directRecipientJid = isGroup
275
+ ? recipientJid
276
+ : await this.resolveDirectRecipientLid((0, jid_1.toUserJid)(recipientJid));
277
+ const publishResult = isGroup
278
+ ? this.shouldUseGroupDirectPath(messageWithIcdc)
279
+ ? await this.publishGroupDirectMessage(recipientJid, envelope)
280
+ : await this.publishGroupSenderKeyMessage(recipientJid, envelope)
281
+ : await this.publishDirectSignalMessageWithFanout(directRecipientJid, envelope);
282
+ return upload ? { ...publishResult, upload } : publishResult;
283
+ }
284
+ /**
285
+ * For a 1:1 recipient passed in PN form, returns the LID-addressed user JID
286
+ * (cache-first; falls back to a one-shot `queryLidsByPhoneJids`). Switching
287
+ * to LID before fanout ensures the envelope, eligible-requester list, and
288
+ * retry-receipt addressing all agree, which keeps the retry tracker from
289
+ * rejecting receipts that arrive in LID form. Returns the original PN if
290
+ * no LID is known/resolvable. Inputs already in LID form pass through.
291
+ */
292
+ async resolveDirectRecipientLid(pnUserJid) {
293
+ if ((0, jid_1.isLidJid)(pnUserJid))
294
+ return pnUserJid;
295
+ const cached = await this.deps.deviceListStore.findByAnyUserJid(pnUserJid);
296
+ if (cached) {
297
+ if ((0, jid_1.isLidJid)(cached.userJid))
298
+ return cached.userJid;
299
+ if (cached.altUserJid && (0, jid_1.isLidJid)(cached.altUserJid))
300
+ return cached.altUserJid;
301
+ }
302
+ try {
303
+ const results = await this.deps.signalDeviceSync.queryLidsByPhoneJids([pnUserJid]);
304
+ const match = results.find((entry) => entry.phoneJid === pnUserJid);
305
+ if (match?.lidJid)
306
+ return match.lidJid;
307
+ }
308
+ catch (error) {
309
+ this.deps.logger.debug('lid resolution failed for direct recipient', {
310
+ pnUserJid,
311
+ message: (0, primitives_2.toError)(error).message
312
+ });
313
+ }
314
+ return pnUserJid;
161
315
  }
162
316
  async syncSignalSession(jid, reasonIdentity = false) {
163
317
  const address = (0, jid_1.parseSignalAddressFromJid)(jid);
164
318
  if (address.server === constants_1.WA_DEFAULTS.GROUP_SERVER) {
165
319
  throw new Error('syncSignalSession supports only direct chats');
166
320
  }
167
- await this.sessionResolver.ensureSession(address, jid, undefined, reasonIdentity);
321
+ await this.deps.sessionResolver.ensureSession(address, jid, undefined, reasonIdentity);
168
322
  }
169
323
  async sendReceipt(input) {
170
- await this.messageClient.sendReceipt(input);
324
+ await this.deps.messageClient.sendReceipt(input);
325
+ }
326
+ async publishProtocolMessageToDevice(deviceJid, protocolMessage, options) {
327
+ const meJid = this.deps.getCurrentCredentials()?.meJid;
328
+ const meParsed = meJid ? (0, jid_1.parseJidFull)(meJid) : undefined;
329
+ const meUserJid = meParsed?.userJid;
330
+ let senderIcdc = null;
331
+ if (meUserJid) {
332
+ const regInfo = await this.deps.signalStore.getRegistrationInfo();
333
+ const localPubKey = regInfo?.identityKeyPair.pubKey;
334
+ const localIdentity = meParsed && localPubKey
335
+ ? { address: meParsed.address, pubKey: localPubKey }
336
+ : undefined;
337
+ senderIcdc = await this.resolveUserIcdc(meUserJid, localIdentity);
338
+ }
339
+ const message = (0, icdc_1.injectDeviceListMetadata)({ protocolMessage }, senderIcdc, null);
340
+ return this.publishSignalMessage({
341
+ to: deviceJid,
342
+ plaintext: _proto_1.proto.Message.encode(message).finish(),
343
+ id: options?.id,
344
+ type: 'text',
345
+ category: 'peer',
346
+ pushPriority: options?.pushPriority ?? 'high',
347
+ metaNode: (0, message_1.buildMetaNode)({ appdata: 'default' })
348
+ });
349
+ }
350
+ async publishStatusMessage(input) {
351
+ if (input.recipients.length === 0) {
352
+ throw new Error('publishStatusMessage requires at least one recipient');
353
+ }
354
+ this.requireCurrentMeJid('publishStatusMessage');
355
+ const meLid = this.deps.getCurrentCredentials()?.meLid;
356
+ if (!meLid) {
357
+ throw new Error('publishStatusMessage requires current me lid');
358
+ }
359
+ const senderJid = (0, jid_1.normalizeDeviceJid)(meLid);
360
+ const meUserLid = (0, jid_1.toUserJid)(meLid);
361
+ const seen = new Set();
362
+ const recipientsWithSelf = [];
363
+ for (const jid of input.recipients) {
364
+ if (seen.has(jid))
365
+ continue;
366
+ seen.add(jid);
367
+ recipientsWithSelf.push(jid);
368
+ }
369
+ if (!seen.has(meUserLid)) {
370
+ recipientsWithSelf.push(meUserLid);
371
+ }
372
+ const statusSetting = input.statusSetting ?? 'contacts';
373
+ return this.publishSenderKeyFanout({
374
+ groupJid: constants_1.WA_DEFAULTS.STATUS_BROADCAST_JID,
375
+ senderJid,
376
+ recipients: recipientsWithSelf,
377
+ message: input.message,
378
+ options: input.options ?? {},
379
+ logTag: 'status',
380
+ replayStatusSetting: statusSetting,
381
+ // Bare `<to jid=user>` ack hints route the skmsg through primary
382
+ // devices that already hold the sender key.
383
+ customize: async ({ fanoutDeviceJids, distributionParticipants, messageWithSecret, sendOptions }) => {
384
+ const distributedAddressKeys = new Set();
385
+ for (let i = 0; i < distributionParticipants.length; i += 1) {
386
+ distributedAddressKeys.add((0, jid_1.signalAddressKey)(distributionParticipants[i].address));
387
+ }
388
+ const ackHints = [];
389
+ const seenAck = new Set();
390
+ for (let i = 0; i < fanoutDeviceJids.length; i += 1) {
391
+ const deviceJid = fanoutDeviceJids[i];
392
+ const address = (0, jid_1.parseSignalAddressFromJid)(deviceJid);
393
+ if (distributedAddressKeys.has((0, jid_1.signalAddressKey)(address)))
394
+ continue;
395
+ if (address.device !== 0)
396
+ continue;
397
+ const userJid = (0, jid_1.toUserJid)(deviceJid);
398
+ if (seenAck.has(userJid))
399
+ continue;
400
+ seenAck.add(userJid);
401
+ ackHints.push({ jid: userJid });
402
+ }
403
+ const reportingArtifacts = await this.tryBuildReportingTokenArtifacts({
404
+ message: messageWithSecret,
405
+ stanzaId: sendOptions.id,
406
+ senderUserJid: (0, jid_1.toUserJid)(senderJid),
407
+ remoteJid: constants_1.WA_DEFAULTS.STATUS_BROADCAST_JID,
408
+ context: 'status'
409
+ });
410
+ const customNodes = [(0, message_1.buildMetaNode)({ status_setting: statusSetting })];
411
+ if (reportingArtifacts?.node)
412
+ customNodes.push(reportingArtifacts.node);
413
+ return {
414
+ extraParticipants: ackHints,
415
+ customNodes
416
+ };
417
+ }
418
+ });
419
+ }
420
+ async publishBroadcastListMessage(input) {
421
+ if (input.recipients.length === 0) {
422
+ throw new Error('publishBroadcastListMessage requires at least one recipient');
423
+ }
424
+ const meJid = this.requireCurrentMeJid('publishBroadcastListMessage');
425
+ const senderJid = (0, jid_1.normalizeDeviceJid)(meJid);
426
+ return this.publishSenderKeyFanout({
427
+ groupJid: input.listJid,
428
+ senderJid,
429
+ recipients: input.recipients,
430
+ message: input.message,
431
+ options: input.options ?? {},
432
+ logTag: 'broadcast list',
433
+ customize: ({ fanoutDeviceJids }) => {
434
+ const phashTargets = new Array(fanoutDeviceJids.length + 1);
435
+ let phashTargetCount = 0;
436
+ for (let i = 0; i < fanoutDeviceJids.length; i += 1) {
437
+ const candidate = fanoutDeviceJids[i];
438
+ if ((0, jid_1.isHostedDeviceJid)(candidate))
439
+ continue;
440
+ phashTargets[phashTargetCount] = candidate;
441
+ phashTargetCount += 1;
442
+ }
443
+ phashTargets[phashTargetCount] = senderJid;
444
+ phashTargets.length = phashTargetCount + 1;
445
+ return Promise.resolve({ phash: (0, phash_1.computePhashV2)(phashTargets) });
446
+ }
447
+ });
448
+ }
449
+ async publishSenderKeyFanout(input) {
450
+ const sendOptions = await this.withResolvedMessageId(input.options);
451
+ const sender = (0, jid_1.parseSignalAddressFromJid)(input.senderJid);
452
+ const messageWithSecret = await (0, _message_1.ensureMessageSecret)(input.message);
453
+ const plaintext = await (0, padding_1.writeRandomPadMax16)(_proto_1.proto.Message.encode(messageWithSecret).finish());
454
+ const { distributionMessage, ciphertext: groupCiphertext, keyId: senderKeyId } = await this.deps.senderKeyManager.prepareGroupEncryption(input.groupJid, sender, plaintext);
455
+ const { fanoutDeviceJids, distributionParticipants } = await this.encryptGroupDistributionParticipants(input.groupJid, senderKeyId, distributionMessage, input.recipients);
456
+ let shouldAttachDeviceIdentity = false;
457
+ for (let i = 0; i < distributionParticipants.length; i += 1) {
458
+ if (distributionParticipants[i].encType === 'pkmsg') {
459
+ shouldAttachDeviceIdentity = true;
460
+ break;
461
+ }
462
+ }
463
+ const extras = input.customize
464
+ ? await input.customize({
465
+ fanoutDeviceJids,
466
+ distributionParticipants,
467
+ messageWithSecret,
468
+ sendOptions
469
+ })
470
+ : {};
471
+ const participants = distributionParticipants.map((p) => ({
472
+ jid: p.jid,
473
+ encType: p.encType,
474
+ ciphertext: p.ciphertext
475
+ }));
476
+ if (extras.extraParticipants) {
477
+ for (const entry of extras.extraParticipants) {
478
+ participants.push(entry);
479
+ }
480
+ }
481
+ const messageNode = (0, message_1.buildGroupSenderKeyMessageNode)({
482
+ to: input.groupJid,
483
+ type: (0, content_1.resolveMessageTypeAttr)(messageWithSecret),
484
+ id: sendOptions.id,
485
+ phash: extras.phash,
486
+ edit: (0, content_1.resolveEditAttr)(messageWithSecret) ?? undefined,
487
+ mediatype: (0, content_1.resolveEncMediaType)(messageWithSecret) ?? undefined,
488
+ decryptFail: (0, content_1.resolveDecryptFailAttr)(messageWithSecret),
489
+ groupCiphertext: groupCiphertext.ciphertext,
490
+ participants,
491
+ deviceIdentity: shouldAttachDeviceIdentity
492
+ ? this.getEncodedSignedDeviceIdentity()
493
+ : undefined,
494
+ customNodes: extras.customNodes,
495
+ additionalAttributes: sendOptions.additionalAttributes
496
+ });
497
+ const replayPayload = {
498
+ mode: 'plaintext',
499
+ to: input.groupJid,
500
+ type: messageNode.attrs.type,
501
+ plaintext,
502
+ ...(input.replayStatusSetting ? { statusSetting: input.replayStatusSetting } : {})
503
+ };
504
+ const result = await this.deps.retryTracker.track({
505
+ messageIdHint: messageNode.attrs.id ?? sendOptions.id,
506
+ toJid: input.groupJid,
507
+ replayPayload,
508
+ eligibleRequesterDeviceJids: undefined
509
+ }, async () => this.deps.messageClient.publishNode(messageNode, sendOptions));
510
+ const distributedAddresses = new Array(distributionParticipants.length);
511
+ for (let i = 0; i < distributionParticipants.length; i += 1) {
512
+ distributedAddresses[i] = distributionParticipants[i].address;
513
+ }
514
+ try {
515
+ await this.deps.senderKeyManager.markSenderKeyDistributed(input.groupJid, senderKeyId, distributedAddresses);
516
+ }
517
+ catch (error) {
518
+ this.deps.logger.warn('failed to mark sender key distribution targets', {
519
+ logTag: input.logTag,
520
+ groupJid: input.groupJid,
521
+ participants: distributedAddresses.length,
522
+ message: (0, primitives_2.toError)(error).message
523
+ });
524
+ }
525
+ return result;
171
526
  }
172
527
  async requestAppStateSyncKeys(keyIds) {
173
- return this.appStateSyncKeyProtocol.requestKeys(keyIds);
528
+ return this.deps.appStateSyncKeyProtocol.requestKeys(keyIds);
174
529
  }
175
530
  async sendAppStateSyncKeyShare(toDeviceJid, keys, missingKeyIds = []) {
176
- await this.appStateSyncKeyProtocol.sendKeyShare(toDeviceJid, keys, missingKeyIds);
531
+ await this.deps.appStateSyncKeyProtocol.sendKeyShare(toDeviceJid, keys, missingKeyIds);
177
532
  }
178
- async mutateParticipantsCacheFromGroupEvent(event) {
179
- await this.participantsCache.mutateFromGroupEvent(event);
533
+ async mutateGroupMetadataCacheFromGroupEvent(event) {
534
+ await this.deps.groupMetadataCache.mutateFromGroupEvent(event);
180
535
  }
536
+ // noop for now
181
537
  shouldUseGroupDirectPath(message) {
182
- const protocolType = message.protocolMessage?.type;
183
- if (protocolType === _proto_1.proto.Message.ProtocolMessage.Type.REVOKE ||
184
- protocolType === _proto_1.proto.Message.ProtocolMessage.Type.MESSAGE_EDIT) {
185
- return true;
186
- }
187
- return message.keepInChatMessage?.keepType === _proto_1.proto.KeepType.UNDO_KEEP_FOR_ALL;
538
+ return false;
188
539
  }
189
- async publishGroupDirectMessage(groupJid, message, plaintext, type, options, retryContext = {}, edit, mediatype, metaNode) {
190
- const sendOptions = await this.withResolvedMessageId(options);
540
+ async publishGroupDirectMessage(groupJid, envelope, retryContext = {}) {
541
+ const { message, plaintext, type, edit, mediatype, sendOptions } = envelope;
191
542
  const meJid = this.requireCurrentMeJid('sendMessage');
192
543
  const participantUserJids = retryContext.forceRefreshParticipants
193
- ? await this.participantsCache.refreshParticipantUsers(groupJid)
194
- : await this.participantsCache.resolveParticipantUsers(groupJid);
544
+ ? await this.deps.groupMetadataCache.refreshParticipantUsers(groupJid)
545
+ : await this.deps.groupMetadataCache.resolveParticipantUsers(groupJid);
195
546
  const addressingMode = retryContext.forceAddressingMode ??
196
547
  this.resolveGroupAddressingMode(participantUserJids, groupJid);
197
548
  const senderForPhash = this.resolveSenderForAddressingMode(addressingMode, meJid);
198
- const fanoutDeviceJids = await this.fanoutResolver.resolveGroupParticipantDeviceJids(participantUserJids);
549
+ const fanoutDeviceJids = await this.deps.fanoutResolver.resolveGroupParticipantDeviceJids(participantUserJids);
199
550
  if (fanoutDeviceJids.length === 0) {
200
551
  throw new Error('group direct send resolved no target devices');
201
552
  }
202
- const resolvedFanoutTargets = await this.sessionResolver.ensureSessionsBatch(fanoutDeviceJids);
553
+ const resolvedFanoutTargets = await this.deps.sessionResolver.ensureSessionsBatch(fanoutDeviceJids);
554
+ const resolvedNormalizedJids = new Set();
555
+ for (let index = 0; index < resolvedFanoutTargets.length; index += 1) {
556
+ resolvedNormalizedJids.add(resolvedFanoutTargets[index].jid);
557
+ }
203
558
  const uniqueNormalizedFanoutJids = new Set();
204
559
  for (let index = 0; index < fanoutDeviceJids.length; index += 1) {
205
560
  uniqueNormalizedFanoutJids.add((0, jid_1.normalizeDeviceJid)(fanoutDeviceJids[index]));
206
561
  }
207
- if (resolvedFanoutTargets.length !== uniqueNormalizedFanoutJids.size) {
208
- throw new Error('group direct send resolved incomplete signal sessions');
562
+ const droppedDevices = [];
563
+ for (const expected of uniqueNormalizedFanoutJids) {
564
+ if (!resolvedNormalizedJids.has(expected)) {
565
+ droppedDevices.push(expected);
566
+ }
567
+ }
568
+ if (droppedDevices.length > 0) {
569
+ this.deps.logger.warn('group direct fanout dropping devices without signal session', {
570
+ groupJid,
571
+ droppedCount: droppedDevices.length,
572
+ totalExpected: uniqueNormalizedFanoutJids.size,
573
+ sample: droppedDevices.slice(0, 3)
574
+ });
575
+ }
576
+ if (resolvedFanoutTargets.length === 0) {
577
+ throw new Error('group direct send resolved no signal sessions');
209
578
  }
210
579
  const participantEncryptRequests = new Array(resolvedFanoutTargets.length);
211
580
  for (let index = 0; index < resolvedFanoutTargets.length; index += 1) {
@@ -215,7 +584,7 @@ class WaMessageDispatchCoordinator {
215
584
  plaintext
216
585
  };
217
586
  }
218
- const encryptedParticipants = await this.signalProtocol.encryptMessagesBatch(participantEncryptRequests, resolvedFanoutTargets);
587
+ const encryptedParticipants = await this.deps.signalProtocol.encryptMessagesBatch(participantEncryptRequests, resolvedFanoutTargets);
219
588
  const participants = new Array(resolvedFanoutTargets.length);
220
589
  for (let index = 0; index < resolvedFanoutTargets.length; index += 1) {
221
590
  const target = resolvedFanoutTargets[index];
@@ -233,20 +602,27 @@ class WaMessageDispatchCoordinator {
233
602
  }
234
603
  }
235
604
  const phashTargets = new Array(resolvedFanoutTargets.length + 1);
605
+ let phashTargetCount = 0;
236
606
  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
- ]);
607
+ const candidate = resolvedFanoutTargets[index].jid;
608
+ if ((0, jid_1.isHostedDeviceJid)(candidate))
609
+ continue;
610
+ phashTargets[phashTargetCount] = candidate;
611
+ phashTargetCount += 1;
612
+ }
613
+ phashTargets[phashTargetCount] = senderForPhash;
614
+ phashTargets.length = phashTargetCount + 1;
615
+ const localPhash = (0, phash_1.computePhashV2)(phashTargets);
616
+ const reportingArtifacts = await this.tryBuildReportingTokenArtifacts({
617
+ message,
618
+ stanzaId: sendOptions.id,
619
+ senderUserJid: (0, jid_1.toUserJid)(senderForPhash),
620
+ remoteJid: groupJid,
621
+ context: 'group_direct'
622
+ });
623
+ const customNodes = envelope.customNodes ? [...envelope.customNodes] : [];
624
+ if (reportingArtifacts?.node)
625
+ customNodes.push(reportingArtifacts.node);
250
626
  const messageNode = (0, message_1.buildDirectMessageFanoutNode)({
251
627
  to: groupJid,
252
628
  type,
@@ -258,9 +634,10 @@ class WaMessageDispatchCoordinator {
258
634
  deviceIdentity: shouldAttachDeviceIdentity
259
635
  ? this.getEncodedSignedDeviceIdentity()
260
636
  : undefined,
261
- reportingNode: reportingArtifacts?.node ?? undefined,
262
- metaNode,
263
- mediatype
637
+ customNodes: customNodes.length > 0 ? customNodes : undefined,
638
+ mediatype,
639
+ decryptFail: envelope.decryptFail,
640
+ additionalAttributes: sendOptions.additionalAttributes
264
641
  });
265
642
  const replayPayload = {
266
643
  mode: 'plaintext',
@@ -268,13 +645,12 @@ class WaMessageDispatchCoordinator {
268
645
  type,
269
646
  plaintext
270
647
  };
271
- const result = await this.retryTracker.track({
272
- messageIdHint: sendOptions.id ?? messageNode.attrs.id,
648
+ const result = await this.deps.retryTracker.track({
649
+ messageIdHint: messageNode.attrs.id ?? sendOptions.id,
273
650
  toJid: groupJid,
274
- type,
275
651
  replayPayload,
276
652
  eligibleRequesterDeviceJids: undefined
277
- }, async () => this.messageClient.publishNode(messageNode, sendOptions));
653
+ }, async () => this.deps.messageClient.publishNode(messageNode, sendOptions));
278
654
  const ackError = result.ack.error;
279
655
  const serverPhash = result.ack.phash;
280
656
  const serverAddressingMode = result.ack.addressingMode;
@@ -283,7 +659,7 @@ class WaMessageDispatchCoordinator {
283
659
  const hasAddressingError = ackError === 421;
284
660
  if (!retryContext.retried &&
285
661
  (hasPhashMismatch || hasAddressingMismatch || hasAddressingError)) {
286
- this.logger.warn('group direct publish acknowledged with mismatch metadata', {
662
+ this.deps.logger.warn('group direct publish acknowledged with mismatch metadata', {
287
663
  id: result.id,
288
664
  groupJid,
289
665
  localPhash,
@@ -292,28 +668,88 @@ class WaMessageDispatchCoordinator {
292
668
  serverAddressingMode,
293
669
  ackError
294
670
  });
295
- return this.publishGroupDirectMessage(groupJid, message, plaintext, type, {
296
- ...sendOptions,
297
- id: result.id
671
+ return this.publishGroupDirectMessage(groupJid, {
672
+ ...envelope,
673
+ sendOptions: { ...sendOptions, id: result.id }
298
674
  }, {
299
675
  retried: true,
300
676
  forceRefreshParticipants: true,
301
677
  forceAddressingMode: serverAddressingMode
302
- }, edit, mediatype, metaNode);
678
+ });
303
679
  }
304
680
  return result;
305
681
  }
306
- async publishGroupSenderKeyMessage(groupJid, message, plaintext, type, options, retryContext = {}, edit, mediatype, metaNode) {
307
- const sendOptions = await this.withResolvedMessageId(options);
682
+ // Returns null on any failure so the group send still goes out unchanged.
683
+ async buildBotSidecarParticipant(message) {
684
+ const botJid = (0, bot_1.extractInvokedBotJid)(message);
685
+ if (!botJid)
686
+ return null;
687
+ let address;
688
+ try {
689
+ address = (0, jid_1.parseSignalAddressFromJid)(botJid);
690
+ }
691
+ catch (error) {
692
+ this.deps.logger.debug('bot sidecar: failed to parse bot jid', {
693
+ botJid,
694
+ message: (0, primitives_2.toError)(error).message
695
+ });
696
+ return null;
697
+ }
698
+ let resolvedTargets;
699
+ try {
700
+ resolvedTargets = await this.deps.sessionResolver.ensureSessionsBatch([botJid]);
701
+ }
702
+ catch (error) {
703
+ this.deps.logger.debug('bot sidecar: signal session sync failed', {
704
+ botJid,
705
+ message: (0, primitives_2.toError)(error).message
706
+ });
707
+ return null;
708
+ }
709
+ if (resolvedTargets.length === 0) {
710
+ this.deps.logger.debug('bot sidecar: signal session not established', { botJid });
711
+ return null;
712
+ }
713
+ // The bot seeds its streaming-response keys from this HKDF derivation.
714
+ const parentMessageSecret = message.messageContextInfo?.messageSecret;
715
+ const botMessageSecret = parentMessageSecret && parentMessageSecret.byteLength > 0
716
+ ? (0, bot_1.genBotMsgSecret)(parentMessageSecret)
717
+ : undefined;
718
+ const botCopy = (0, bot_1.buildBotInvokeProtoCopy)(message, botMessageSecret);
719
+ const botPlaintext = await (0, padding_1.writeRandomPadMax16)(_proto_1.proto.Message.encode(botCopy).finish());
720
+ try {
721
+ const [encrypted] = await this.deps.signalProtocol.encryptMessagesBatch([{ address, plaintext: botPlaintext }], resolvedTargets.map((target) => ({
722
+ address: target.address,
723
+ session: target.session
724
+ })));
725
+ if (!encrypted)
726
+ return null;
727
+ this.deps.logger.trace('bot sidecar encrypted', { botJid, encType: encrypted.type });
728
+ return {
729
+ jid: botJid,
730
+ encType: encrypted.type,
731
+ ciphertext: encrypted.ciphertext
732
+ };
733
+ }
734
+ catch (error) {
735
+ this.deps.logger.debug('bot sidecar: encryption failed', {
736
+ botJid,
737
+ message: (0, primitives_2.toError)(error).message
738
+ });
739
+ return null;
740
+ }
741
+ }
742
+ async publishGroupSenderKeyMessage(groupJid, envelope, retryContext = {}) {
743
+ const { message, plaintext, type, edit, mediatype, sendOptions } = envelope;
308
744
  const meJid = this.requireCurrentMeJid('sendMessage');
309
745
  const participantUserJids = retryContext.forceRefreshParticipants
310
- ? await this.participantsCache.refreshParticipantUsers(groupJid)
311
- : await this.participantsCache.resolveParticipantUsers(groupJid);
746
+ ? await this.deps.groupMetadataCache.refreshParticipantUsers(groupJid)
747
+ : await this.deps.groupMetadataCache.resolveParticipantUsers(groupJid);
312
748
  const addressingMode = retryContext.forceAddressingMode ??
313
749
  this.resolveGroupAddressingMode(participantUserJids, groupJid);
314
750
  const senderJid = this.resolveSenderForAddressingMode(addressingMode, meJid);
315
751
  const sender = (0, jid_1.parseSignalAddressFromJid)(senderJid);
316
- const { distributionMessage: senderKeyDistributionMessage, ciphertext: groupCiphertext, keyId: senderKeyId } = await this.senderKeyManager.prepareGroupEncryption(groupJid, sender, plaintext);
752
+ const { distributionMessage: senderKeyDistributionMessage, ciphertext: groupCiphertext, keyId: senderKeyId } = await this.deps.senderKeyManager.prepareGroupEncryption(groupJid, sender, plaintext);
317
753
  const distributionData = await this.distributionDedup.run(`dist:${groupJid}:${senderKeyId}`, () => this.encryptGroupDistributionParticipants(groupJid, senderKeyId, senderKeyDistributionMessage, participantUserJids));
318
754
  const { fanoutDeviceJids, distributionParticipants } = distributionData;
319
755
  let shouldAttachDeviceIdentity = false;
@@ -324,20 +760,28 @@ class WaMessageDispatchCoordinator {
324
760
  }
325
761
  }
326
762
  const phashTargets = new Array(fanoutDeviceJids.length + 1);
763
+ let phashTargetCount = 0;
327
764
  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
- ]);
765
+ const candidate = fanoutDeviceJids[index];
766
+ if ((0, jid_1.isHostedDeviceJid)(candidate))
767
+ continue;
768
+ phashTargets[phashTargetCount] = candidate;
769
+ phashTargetCount += 1;
770
+ }
771
+ phashTargets[phashTargetCount] = senderJid;
772
+ phashTargets.length = phashTargetCount + 1;
773
+ const localPhash = (0, phash_1.computePhashV2)(phashTargets);
774
+ const reportingArtifacts = await this.tryBuildReportingTokenArtifacts({
775
+ message,
776
+ stanzaId: sendOptions.id,
777
+ senderUserJid: (0, jid_1.toUserJid)(senderJid),
778
+ remoteJid: groupJid,
779
+ context: 'group_sender_key'
780
+ });
781
+ const botSidecar = await this.buildBotSidecarParticipant(message);
782
+ const customNodes = envelope.customNodes ? [...envelope.customNodes] : [];
783
+ if (reportingArtifacts?.node)
784
+ customNodes.push(reportingArtifacts.node);
341
785
  const messageNode = (0, message_1.buildGroupSenderKeyMessageNode)({
342
786
  to: groupJid,
343
787
  type,
@@ -347,12 +791,14 @@ class WaMessageDispatchCoordinator {
347
791
  addressingMode,
348
792
  groupCiphertext: groupCiphertext.ciphertext,
349
793
  participants: distributionParticipants,
350
- deviceIdentity: shouldAttachDeviceIdentity
794
+ deviceIdentity: shouldAttachDeviceIdentity || botSidecar?.encType === 'pkmsg'
351
795
  ? this.getEncodedSignedDeviceIdentity()
352
796
  : undefined,
353
- reportingNode: reportingArtifacts?.node ?? undefined,
354
- metaNode,
355
- mediatype
797
+ customNodes: customNodes.length > 0 ? customNodes : undefined,
798
+ mediatype,
799
+ decryptFail: envelope.decryptFail,
800
+ botParticipants: botSidecar ? [botSidecar] : undefined,
801
+ additionalAttributes: sendOptions.additionalAttributes
356
802
  });
357
803
  const replayPayload = {
358
804
  mode: 'plaintext',
@@ -360,25 +806,24 @@ class WaMessageDispatchCoordinator {
360
806
  type,
361
807
  plaintext
362
808
  };
363
- const result = await this.retryTracker.track({
364
- messageIdHint: sendOptions.id ?? messageNode.attrs.id,
809
+ const result = await this.deps.retryTracker.track({
810
+ messageIdHint: messageNode.attrs.id ?? sendOptions.id,
365
811
  toJid: groupJid,
366
- type,
367
812
  replayPayload,
368
813
  eligibleRequesterDeviceJids: undefined
369
- }, async () => this.messageClient.publishNode(messageNode, sendOptions));
814
+ }, async () => this.deps.messageClient.publishNode(messageNode, sendOptions));
370
815
  const distributedAddresses = new Array(distributionParticipants.length);
371
816
  for (let index = 0; index < distributionParticipants.length; index += 1) {
372
817
  distributedAddresses[index] = distributionParticipants[index].address;
373
818
  }
374
819
  try {
375
- await this.senderKeyManager.markSenderKeyDistributed(groupJid, senderKeyId, distributedAddresses);
820
+ await this.deps.senderKeyManager.markSenderKeyDistributed(groupJid, senderKeyId, distributedAddresses);
376
821
  }
377
822
  catch (error) {
378
- this.logger.warn('failed to mark sender key distribution targets', {
823
+ this.deps.logger.warn('failed to mark sender key distribution targets', {
379
824
  groupJid,
380
825
  participants: distributedAddresses.length,
381
- message: (0, primitives_1.toError)(error).message
826
+ message: (0, primitives_2.toError)(error).message
382
827
  });
383
828
  }
384
829
  const ackError = result.ack.error;
@@ -389,7 +834,7 @@ class WaMessageDispatchCoordinator {
389
834
  const hasAddressingError = ackError === 421;
390
835
  if (!retryContext.retried &&
391
836
  (hasPhashMismatch || hasAddressingMismatch || hasAddressingError)) {
392
- this.logger.warn('group message publish acknowledged with mismatch metadata', {
837
+ this.deps.logger.warn('group message publish acknowledged with mismatch metadata', {
393
838
  id: result.id,
394
839
  groupJid,
395
840
  localPhash,
@@ -398,30 +843,24 @@ class WaMessageDispatchCoordinator {
398
843
  serverAddressingMode,
399
844
  ackError
400
845
  });
401
- return this.publishGroupSenderKeyMessage(groupJid, message, plaintext, type, {
402
- ...sendOptions,
403
- id: result.id
846
+ return this.publishGroupSenderKeyMessage(groupJid, {
847
+ ...envelope,
848
+ sendOptions: { ...sendOptions, id: result.id }
404
849
  }, {
405
850
  retried: true,
406
851
  forceRefreshParticipants: true,
407
852
  forceAddressingMode: serverAddressingMode
408
- }, edit, mediatype, metaNode);
853
+ });
409
854
  }
410
855
  return result;
411
856
  }
412
857
  resolveGroupAddressingMode(participantUserJids, groupJid) {
413
858
  for (let index = 0; index < participantUserJids.length; index += 1) {
414
- const participantJid = participantUserJids[index];
415
- try {
416
- if ((0, jid_1.splitJid)(participantJid).server === 'lid') {
417
- return 'lid';
418
- }
419
- }
420
- catch (error) {
421
- this.logger.trace('ignoring malformed participant jid in addressing mode resolution', { participantJid, message: (0, primitives_1.toError)(error).message });
859
+ if ((0, jid_1.isLidJid)(participantUserJids[index])) {
860
+ return 'lid';
422
861
  }
423
862
  }
424
- this.logger.trace('group addressing mode resolved to pn (default)', {
863
+ this.deps.logger.trace('group addressing mode resolved to pn (default)', {
425
864
  groupJid,
426
865
  participants: participantUserJids.length
427
866
  });
@@ -429,15 +868,15 @@ class WaMessageDispatchCoordinator {
429
868
  }
430
869
  resolveSenderForAddressingMode(addressingMode, meJid) {
431
870
  if (addressingMode === 'lid') {
432
- const meLid = this.getCurrentMeLid();
871
+ const meLid = this.deps.getCurrentCredentials()?.meLid;
433
872
  if (meLid && meLid.includes('@')) {
434
873
  try {
435
874
  return (0, jid_1.normalizeDeviceJid)(meLid);
436
875
  }
437
876
  catch (error) {
438
- this.logger.trace('ignoring malformed me lid jid', {
877
+ this.deps.logger.trace('ignoring malformed me lid jid', {
439
878
  meLid,
440
- message: (0, primitives_1.toError)(error).message
879
+ message: (0, primitives_2.toError)(error).message
441
880
  });
442
881
  }
443
882
  }
@@ -448,7 +887,7 @@ class WaMessageDispatchCoordinator {
448
887
  const distributionPayload = await (0, padding_1.writeRandomPadMax16)(_proto_1.proto.Message.encode({
449
888
  senderKeyDistributionMessage
450
889
  }).finish());
451
- const fanoutDeviceJids = await this.fanoutResolver.resolveGroupParticipantDeviceJids(participantUserJids);
890
+ const fanoutDeviceJids = await this.deps.fanoutResolver.resolveGroupParticipantDeviceJids(participantUserJids);
452
891
  if (fanoutDeviceJids.length === 0) {
453
892
  return {
454
893
  fanoutDeviceJids,
@@ -461,9 +900,9 @@ class WaMessageDispatchCoordinator {
461
900
  const jid = fanoutDeviceJids[index];
462
901
  const address = (0, jid_1.parseSignalAddressFromJid)(jid);
463
902
  fanoutAddresses[index] = address;
464
- fanoutTargetsByAddressKey.set((0, jid_2.signalAddressKey)(address), { jid, address });
903
+ fanoutTargetsByAddressKey.set((0, jid_1.signalAddressKey)(address), { jid, address });
465
904
  }
466
- const pendingAddresses = await this.senderKeyManager.filterParticipantsNeedingDistribution(groupJid, senderKeyId, fanoutAddresses);
905
+ const pendingAddresses = await this.deps.senderKeyManager.filterParticipantsNeedingDistribution(groupJid, senderKeyId, fanoutAddresses);
467
906
  if (pendingAddresses.length === 0) {
468
907
  return {
469
908
  fanoutDeviceJids,
@@ -473,7 +912,7 @@ class WaMessageDispatchCoordinator {
473
912
  const pendingAddressKeys = new Set();
474
913
  const pendingTargets = [];
475
914
  for (let index = 0; index < pendingAddresses.length; index += 1) {
476
- const key = (0, jid_2.signalAddressKey)(pendingAddresses[index]);
915
+ const key = (0, jid_1.signalAddressKey)(pendingAddresses[index]);
477
916
  if (pendingAddressKeys.has(key)) {
478
917
  continue;
479
918
  }
@@ -496,16 +935,16 @@ class WaMessageDispatchCoordinator {
496
935
  let availableTargets = [];
497
936
  let prefetchedAvailableTargets;
498
937
  try {
499
- const resolvedTargets = await this.sessionResolver.ensureSessionsBatch(pendingTargetJids);
938
+ const resolvedTargets = await this.deps.sessionResolver.ensureSessionsBatch(pendingTargetJids);
500
939
  availableTargets = resolvedTargets;
501
940
  prefetchedAvailableTargets = resolvedTargets;
502
941
  }
503
942
  catch (error) {
504
- const normalized = (0, primitives_1.toError)(error);
943
+ const normalized = (0, primitives_2.toError)(error);
505
944
  if (normalized.message === 'identity mismatch') {
506
945
  throw normalized;
507
946
  }
508
- this.logger.warn('group sender-key distribution session sync failed, continuing with available sessions', {
947
+ this.deps.logger.warn('group sender-key distribution session sync failed, continuing with available sessions', {
509
948
  groupJid,
510
949
  requested: pendingTargetJids.length,
511
950
  message: normalized.message
@@ -514,7 +953,7 @@ class WaMessageDispatchCoordinator {
514
953
  for (let index = 0; index < pendingTargets.length; index += 1) {
515
954
  pendingTargetAddresses[index] = pendingTargets[index].address;
516
955
  }
517
- const hasPendingSessions = await this.signalStore.hasSessions(pendingTargetAddresses);
956
+ const hasPendingSessions = await this.deps.sessionStore.hasSessions(pendingTargetAddresses);
518
957
  const nextAvailableTargets = [];
519
958
  for (let index = 0; index < pendingTargets.length; index += 1) {
520
959
  if (hasPendingSessions[index]) {
@@ -537,7 +976,7 @@ class WaMessageDispatchCoordinator {
537
976
  plaintext: distributionPayload
538
977
  };
539
978
  }
540
- const encryptedDistributionParticipants = await this.signalProtocol.encryptMessagesBatch(distributionEncryptRequests, prefetchedAvailableTargets);
979
+ const encryptedDistributionParticipants = await this.deps.signalProtocol.encryptMessagesBatch(distributionEncryptRequests, prefetchedAvailableTargets);
541
980
  const distributionParticipants = new Array(availableTargets.length);
542
981
  for (let index = 0; index < availableTargets.length; index += 1) {
543
982
  const target = availableTargets[index];
@@ -553,12 +992,12 @@ class WaMessageDispatchCoordinator {
553
992
  distributionParticipants
554
993
  };
555
994
  }
556
- async publishDirectSignalMessageWithFanout(recipientJid, message, plaintext, type, options, edit, mediatype, metaNode) {
557
- const sendOptions = await this.withResolvedMessageId(options);
995
+ async publishDirectSignalMessageWithFanout(recipientJid, envelope) {
996
+ const { message, plaintext, type, edit, mediatype, sendOptions } = envelope;
558
997
  const meJid = this.requireCurrentMeJid('sendMessage');
559
- const meLid = this.getCurrentMeLid();
560
- const selfDeviceJidForRecipient = this.fanoutResolver.resolveSelfDeviceJidForRecipient(recipientJid, meJid, meLid);
561
- const deviceJids = await this.fanoutResolver.resolveDirectFanoutDeviceJids(recipientJid, selfDeviceJidForRecipient);
998
+ const meLid = this.deps.getCurrentCredentials()?.meLid;
999
+ const selfDeviceJidForRecipient = this.deps.fanoutResolver.resolveSelfDeviceJidForRecipient(recipientJid, meJid, meLid);
1000
+ const deviceJids = await this.deps.fanoutResolver.resolveDirectFanoutDeviceJids(recipientJid, selfDeviceJidForRecipient);
562
1001
  const targets = new Array(deviceJids.length);
563
1002
  for (let index = 0; index < deviceJids.length; index += 1) {
564
1003
  const jid = deviceJids[index];
@@ -571,7 +1010,7 @@ class WaMessageDispatchCoordinator {
571
1010
  }
572
1011
  const recipientUserJid = (0, jid_1.toUserJid)(recipientJid);
573
1012
  const meUserJid = (0, jid_1.toUserJid)(selfDeviceJidForRecipient);
574
- this.logger.debug('wa client publish signal fanout', {
1013
+ this.deps.logger.trace('wa client publish signal fanout', {
575
1014
  to: recipientJid,
576
1015
  devices: deviceJids.length,
577
1016
  type
@@ -585,20 +1024,42 @@ class WaMessageDispatchCoordinator {
585
1024
  }
586
1025
  }
587
1026
  }
588
- const resolvedFanoutTargets = await this.sessionResolver.ensureSessionsBatch(deviceJids, expectedIdentityByJid);
1027
+ const resolvedFanoutTargets = await this.deps.sessionResolver.ensureSessionsBatch(deviceJids, expectedIdentityByJid);
589
1028
  const resolvedFanoutTargetsByJid = new Map();
590
1029
  for (let index = 0; index < resolvedFanoutTargets.length; index += 1) {
591
1030
  const target = resolvedFanoutTargets[index];
592
1031
  resolvedFanoutTargetsByJid.set((0, jid_1.normalizeDeviceJid)(target.jid), target);
593
1032
  }
1033
+ const liveTargets = [];
1034
+ const droppedSecondaryDevices = [];
594
1035
  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');
1036
+ const target = targets[index];
1037
+ if (resolvedFanoutTargetsByJid.has(target.normalizedJid)) {
1038
+ liveTargets.push(target);
1039
+ continue;
597
1040
  }
1041
+ const isPrimaryRecipient = target.userJid === recipientUserJid && target.normalizedJid === target.userJid;
1042
+ if (isPrimaryRecipient) {
1043
+ this.deps.logger.error('direct fanout dropping primary recipient device without signal session', { to: recipientJid, device: target.jid });
1044
+ }
1045
+ else {
1046
+ droppedSecondaryDevices.push(target.jid);
1047
+ }
1048
+ }
1049
+ if (droppedSecondaryDevices.length > 0) {
1050
+ this.deps.logger.warn('direct fanout dropping secondary devices without signal session', {
1051
+ to: recipientJid,
1052
+ droppedCount: droppedSecondaryDevices.length,
1053
+ totalExpected: targets.length,
1054
+ sample: droppedSecondaryDevices.slice(0, 3)
1055
+ });
1056
+ }
1057
+ if (liveTargets.length === 0) {
1058
+ throw new Error('direct fanout missing signal sessions for all targets');
598
1059
  }
599
1060
  let hasSelfDeviceFanout = false;
600
- for (let index = 0; index < targets.length; index += 1) {
601
- if (targets[index].userJid === meUserJid) {
1061
+ for (let index = 0; index < liveTargets.length; index += 1) {
1062
+ if (liveTargets[index].userJid === meUserJid) {
602
1063
  hasSelfDeviceFanout = true;
603
1064
  break;
604
1065
  }
@@ -606,13 +1067,10 @@ class WaMessageDispatchCoordinator {
606
1067
  const selfDevicePlaintext = hasSelfDeviceFanout
607
1068
  ? await (0, padding_1.writeRandomPadMax16)(_proto_1.proto.Message.encode((0, device_sent_1.wrapDeviceSentMessage)(message, recipientUserJid)).finish())
608
1069
  : null;
609
- const participantRequests = new Array(targets.length);
610
- for (let index = 0; index < targets.length; index += 1) {
611
- const target = targets[index];
1070
+ const participantRequests = new Array(liveTargets.length);
1071
+ for (let index = 0; index < liveTargets.length; index += 1) {
1072
+ const target = liveTargets[index];
612
1073
  const resolvedTarget = resolvedFanoutTargetsByJid.get(target.normalizedJid);
613
- if (!resolvedTarget) {
614
- throw new Error('direct fanout missing signal session for target');
615
- }
616
1074
  participantRequests[index] = {
617
1075
  target,
618
1076
  address: resolvedTarget.address,
@@ -637,15 +1095,20 @@ class WaMessageDispatchCoordinator {
637
1095
  session: request.session
638
1096
  };
639
1097
  }
640
- const encryptedParticipants = await this.signalProtocol.encryptMessagesBatch(encryptRequests, prefetchedSessions);
641
- const participants = new Array(participantRequests.length);
1098
+ const encryptedParticipants = await this.deps.signalProtocol.encryptMessagesBatch(encryptRequests, prefetchedSessions);
1099
+ const isBotRecipient = (0, jid_1.isBotJid)(recipientJid);
1100
+ const participants = [];
642
1101
  for (let index = 0; index < participantRequests.length; index += 1) {
643
1102
  const request = participantRequests[index];
644
- participants[index] = {
1103
+ const entry = {
645
1104
  jid: request.target.jid,
646
1105
  encType: encryptedParticipants[index].type,
647
1106
  ciphertext: encryptedParticipants[index].ciphertext
648
1107
  };
1108
+ // wa-web direct 1:1 to bot puts the bot device alongside self devices
1109
+ // inside `<participants>`; the `<bot>` envelope is only used for group
1110
+ // mentions (the sidecar copy) or for bot feedback / revoke flows.
1111
+ participants.push(entry);
649
1112
  }
650
1113
  let shouldAttachDeviceIdentity = false;
651
1114
  for (let index = 0; index < participants.length; index += 1) {
@@ -665,16 +1128,23 @@ class WaMessageDispatchCoordinator {
665
1128
  context: 'direct_fanout'
666
1129
  });
667
1130
  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
- });
1131
+ if (!isBotRecipient) {
1132
+ try {
1133
+ privacyTokenNode =
1134
+ (await this.privacyTokenDedup.run(`pt:${recipientUserJid}`, () => this.deps.resolvePrivacyTokenNode(recipientUserJid))) ?? undefined;
1135
+ }
1136
+ catch (error) {
1137
+ this.deps.logger.warn('privacy token resolution failed', {
1138
+ to: recipientUserJid,
1139
+ message: (0, primitives_2.toError)(error).message
1140
+ });
1141
+ }
677
1142
  }
1143
+ const customNodes = envelope.customNodes ? [...envelope.customNodes] : [];
1144
+ if (reportingArtifacts?.node)
1145
+ customNodes.push(reportingArtifacts.node);
1146
+ if (privacyTokenNode)
1147
+ customNodes.push(privacyTokenNode);
678
1148
  const messageNode = (0, message_1.buildDirectMessageFanoutNode)({
679
1149
  to: recipientJid,
680
1150
  type,
@@ -682,10 +1152,10 @@ class WaMessageDispatchCoordinator {
682
1152
  edit,
683
1153
  participants,
684
1154
  deviceIdentity,
685
- reportingNode: reportingArtifacts?.node ?? undefined,
686
- privacyTokenNode,
687
- metaNode,
688
- mediatype
1155
+ customNodes: customNodes.length > 0 ? customNodes : undefined,
1156
+ mediatype,
1157
+ decryptFail: envelope.decryptFail,
1158
+ additionalAttributes: sendOptions.additionalAttributes
689
1159
  });
690
1160
  const replayPayload = {
691
1161
  mode: 'plaintext',
@@ -693,14 +1163,13 @@ class WaMessageDispatchCoordinator {
693
1163
  type,
694
1164
  plaintext
695
1165
  };
696
- const result = await this.retryTracker.track({
697
- messageIdHint: sendOptions.id ?? messageNode.attrs.id,
1166
+ const result = await this.deps.retryTracker.track({
1167
+ messageIdHint: messageNode.attrs.id ?? sendOptions.id,
698
1168
  toJid: recipientJid,
699
- type,
700
1169
  replayPayload,
701
1170
  eligibleRequesterDeviceJids: deviceJids
702
- }, async () => this.messageClient.publishNode(messageNode, sendOptions));
703
- this.onDirectMessageSent(recipientUserJid);
1171
+ }, async () => this.deps.messageClient.publishNode(messageNode, sendOptions));
1172
+ this.deps.onDirectMessageSent(recipientUserJid);
704
1173
  return result;
705
1174
  }
706
1175
  async withResolvedMessageId(options) {
@@ -722,21 +1191,35 @@ class WaMessageDispatchCoordinator {
722
1191
  async generateOutgoingMessageId() {
723
1192
  try {
724
1193
  const meUserJid = (0, jid_1.toUserJid)(this.requireCurrentMeJid('sendMessage'));
725
- const timestampSeconds = Math.floor(Date.now() / 1000);
726
1194
  const timestampBytes = new Uint8Array(8);
727
- new DataView(timestampBytes.buffer, timestampBytes.byteOffset, timestampBytes.byteLength).setBigUint64(0, BigInt(timestampSeconds), false);
728
- const entropy = (0, bytes_1.concatBytes)([
1195
+ const dv = new DataView(timestampBytes.buffer, timestampBytes.byteOffset, timestampBytes.byteLength);
1196
+ if (this.mobileMessageIdFormat) {
1197
+ dv.setBigUint64(0, BigInt(Date.now()), false);
1198
+ const digest = (0, primitives_1.md5Bytes)([
1199
+ timestampBytes,
1200
+ bytes_1.TEXT_ENCODER.encode(meUserJid),
1201
+ await (0, _crypto_1.randomBytesAsync)(16)
1202
+ ]);
1203
+ digest[0] = 0xac;
1204
+ return (0, bytes_1.bytesToHex)(digest).toUpperCase();
1205
+ }
1206
+ dv.setBigUint64(0, BigInt(Math.floor(Date.now() / 1000)), false);
1207
+ const digest = (0, _crypto_1.sha256)([
729
1208
  timestampBytes,
730
1209
  bytes_1.TEXT_ENCODER.encode(meUserJid),
731
1210
  await (0, _crypto_1.randomBytesAsync)(8)
732
1211
  ]);
733
- const digest = await (0, _crypto_1.sha256)(entropy);
734
1212
  return `3EB0${(0, bytes_1.bytesToHex)(digest.subarray(0, 9)).toUpperCase()}`;
735
1213
  }
736
1214
  catch (error) {
737
- this.logger.warn('failed to generate sha256 message id, falling back to random id', {
738
- message: (0, primitives_1.toError)(error).message
1215
+ this.deps.logger.warn('failed to generate message id, falling back to random', {
1216
+ message: (0, primitives_2.toError)(error).message
739
1217
  });
1218
+ if (this.mobileMessageIdFormat) {
1219
+ const bytes = await (0, _crypto_1.randomBytesAsync)(16);
1220
+ bytes[0] = 0xac;
1221
+ return (0, bytes_1.bytesToHex)(bytes).toUpperCase();
1222
+ }
740
1223
  return `3EB0${(0, bytes_1.bytesToHex)(await (0, _crypto_1.randomBytesAsync)(8)).toUpperCase()}`;
741
1224
  }
742
1225
  }
@@ -753,43 +1236,43 @@ class WaMessageDispatchCoordinator {
753
1236
  });
754
1237
  }
755
1238
  catch (error) {
756
- this.logger.warn('failed to generate reporting token', {
1239
+ this.deps.logger.warn('failed to generate reporting token', {
757
1240
  context: input.context,
758
1241
  id: input.stanzaId,
759
1242
  remoteJid: input.remoteJid,
760
- message: (0, primitives_1.toError)(error).message
1243
+ message: (0, primitives_2.toError)(error).message
761
1244
  });
762
1245
  return null;
763
1246
  }
764
1247
  }
765
1248
  getEncodedSignedDeviceIdentity() {
766
- const signedIdentity = this.getCurrentSignedIdentity();
1249
+ const signedIdentity = this.deps.getCurrentCredentials()?.signedIdentity;
767
1250
  if (!signedIdentity) {
768
- throw new Error('missing signed identity for pkmsg fanout');
1251
+ return undefined;
769
1252
  }
770
1253
  return _proto_1.proto.ADVSignedDeviceIdentity.encode(signedIdentity).finish();
771
1254
  }
772
1255
  resolveUserIcdc(userJid, localIdentity) {
773
1256
  return this.icdcDedup.run(`icdc:${userJid}:${localIdentity ? '1' : '0'}`, async () => {
774
1257
  try {
775
- const snapshots = await this.deviceListStore.getUserDevicesBatch([userJid]);
1258
+ const snapshots = await this.deps.deviceListStore.getUserDevicesBatch([userJid]);
776
1259
  const snapshot = snapshots[0];
777
1260
  if (!snapshot || snapshot.deviceJids.length === 0) {
778
1261
  return null;
779
1262
  }
780
- return (0, icdc_1.resolveIcdcMeta)(snapshot.deviceJids, this.signalStore, snapshot.updatedAtMs, localIdentity);
1263
+ return (0, icdc_1.resolveIcdcMeta)(snapshot.deviceJids, this.deps.identityStore, snapshot.updatedAtMs, localIdentity, this.deps.getIcdcHashLength?.());
781
1264
  }
782
1265
  catch (error) {
783
- this.logger.trace('icdc resolution failed', {
1266
+ this.deps.logger.trace('icdc resolution failed', {
784
1267
  userJid,
785
- message: (0, primitives_1.toError)(error).message
1268
+ message: (0, primitives_2.toError)(error).message
786
1269
  });
787
1270
  return null;
788
1271
  }
789
1272
  });
790
1273
  }
791
1274
  requireCurrentMeJid(context) {
792
- const meJid = this.getCurrentMeJid();
1275
+ const meJid = this.deps.getCurrentCredentials()?.meJid;
793
1276
  if (meJid) {
794
1277
  return meJid;
795
1278
  }
@@ -797,3 +1280,28 @@ class WaMessageDispatchCoordinator {
797
1280
  }
798
1281
  }
799
1282
  exports.WaMessageDispatchCoordinator = WaMessageDispatchCoordinator;
1283
+ function pickContentContextInfo(content) {
1284
+ if (typeof content !== 'object' || content === null)
1285
+ return undefined;
1286
+ if ((0, content_1.isSendTextMessage)(content) || (0, content_1.isSendMediaMessage)(content)) {
1287
+ return content.contextInfo;
1288
+ }
1289
+ return undefined;
1290
+ }
1291
+ function assertNewsletterContextInfoCompatible(ctx) {
1292
+ if (!ctx)
1293
+ return;
1294
+ const unsupported = [];
1295
+ if (ctx.quotedMessageId !== undefined)
1296
+ unsupported.push('quote');
1297
+ if (ctx.mentionedJids?.length)
1298
+ unsupported.push('mentions');
1299
+ if (ctx.isSpoiler === true)
1300
+ unsupported.push('isSpoiler');
1301
+ if (ctx.groupSubject !== undefined || ctx.parentGroupJid !== undefined) {
1302
+ unsupported.push('group invite reply (groupSubject/parentGroupJid)');
1303
+ }
1304
+ if (unsupported.length > 0) {
1305
+ throw new Error(`newsletter sends do not support: ${unsupported.join(', ')}`);
1306
+ }
1307
+ }