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