@pontalabs/baileys 1.0.4 → 1.0.6

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 (447) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +267 -839
  3. package/WAProto/GenerateStatics.sh +3 -4
  4. package/WAProto/WAProto.proto +1215 -511
  5. package/WAProto/fix-imports.js +85 -0
  6. package/WAProto/index.d.ts +14017 -55
  7. package/WAProto/index.js +97689 -29
  8. package/engine-requirements.js +10 -0
  9. package/lib/Defaults/index.d.ts +72 -74
  10. package/lib/Defaults/index.d.ts.map +1 -0
  11. package/lib/Defaults/index.js +94 -108
  12. package/lib/Defaults/index.js.map +1 -0
  13. package/lib/Signal/Group/ciphertext-message.d.ts +8 -7
  14. package/lib/Signal/Group/ciphertext-message.d.ts.map +1 -0
  15. package/lib/Signal/Group/ciphertext-message.js +9 -16
  16. package/lib/Signal/Group/ciphertext-message.js.map +1 -0
  17. package/lib/Signal/Group/group-session-builder.d.ts +11 -13
  18. package/lib/Signal/Group/group-session-builder.d.ts.map +1 -0
  19. package/lib/Signal/Group/group-session-builder.js +19 -61
  20. package/lib/Signal/Group/group-session-builder.js.map +1 -0
  21. package/lib/Signal/Group/group_cipher.d.ts +14 -16
  22. package/lib/Signal/Group/group_cipher.d.ts.map +1 -0
  23. package/lib/Signal/Group/group_cipher.js +41 -70
  24. package/lib/Signal/Group/group_cipher.js.map +1 -0
  25. package/lib/Signal/Group/index.d.ts +12 -11
  26. package/lib/Signal/Group/index.d.ts.map +1 -0
  27. package/lib/Signal/Group/index.js +12 -61
  28. package/lib/Signal/Group/index.js.map +1 -0
  29. package/lib/Signal/Group/keyhelper.d.ts +9 -14
  30. package/lib/Signal/Group/keyhelper.d.ts.map +1 -0
  31. package/lib/Signal/Group/keyhelper.js +10 -58
  32. package/lib/Signal/Group/keyhelper.js.map +1 -0
  33. package/lib/Signal/Group/sender-chain-key.d.ts +13 -13
  34. package/lib/Signal/Group/sender-chain-key.d.ts.map +1 -0
  35. package/lib/Signal/Group/sender-chain-key.js +13 -34
  36. package/lib/Signal/Group/sender-chain-key.js.map +1 -0
  37. package/lib/Signal/Group/sender-key-distribution-message.d.ts +16 -16
  38. package/lib/Signal/Group/sender-key-distribution-message.d.ts.map +1 -0
  39. package/lib/Signal/Group/sender-key-distribution-message.js +28 -36
  40. package/lib/Signal/Group/sender-key-distribution-message.js.map +1 -0
  41. package/lib/Signal/Group/sender-key-message.d.ts +18 -18
  42. package/lib/Signal/Group/sender-key-message.d.ts.map +1 -0
  43. package/lib/Signal/Group/sender-key-message.js +38 -45
  44. package/lib/Signal/Group/sender-key-message.js.map +1 -0
  45. package/lib/Signal/Group/sender-key-name.d.ts +14 -15
  46. package/lib/Signal/Group/sender-key-name.d.ts.map +1 -0
  47. package/lib/Signal/Group/sender-key-name.js +20 -31
  48. package/lib/Signal/Group/sender-key-name.js.map +1 -0
  49. package/lib/Signal/Group/sender-key-record.d.ts +24 -25
  50. package/lib/Signal/Group/sender-key-record.d.ts.map +1 -0
  51. package/lib/Signal/Group/sender-key-record.js +18 -35
  52. package/lib/Signal/Group/sender-key-record.js.map +1 -0
  53. package/lib/Signal/Group/sender-key-state.d.ts +29 -34
  54. package/lib/Signal/Group/sender-key-state.d.ts.map +1 -0
  55. package/lib/Signal/Group/sender-key-state.js +37 -100
  56. package/lib/Signal/Group/sender-key-state.js.map +1 -0
  57. package/lib/Signal/Group/sender-message-key.d.ts +11 -10
  58. package/lib/Signal/Group/sender-message-key.d.ts.map +1 -0
  59. package/lib/Signal/Group/sender-message-key.js +15 -22
  60. package/lib/Signal/Group/sender-message-key.js.map +1 -0
  61. package/lib/Signal/libsignal.d.ts +5 -8
  62. package/lib/Signal/libsignal.d.ts.map +1 -0
  63. package/lib/Signal/libsignal.js +279 -121
  64. package/lib/Signal/libsignal.js.map +1 -0
  65. package/lib/Signal/lid-mapping.d.ts +23 -28
  66. package/lib/Signal/lid-mapping.d.ts.map +1 -0
  67. package/lib/Signal/lid-mapping.js +277 -184
  68. package/lib/Signal/lid-mapping.js.map +1 -0
  69. package/lib/Socket/Client/index.d.ts +3 -2
  70. package/lib/Socket/Client/index.d.ts.map +1 -0
  71. package/lib/Socket/Client/index.js +3 -22
  72. package/lib/Socket/Client/index.js.map +1 -0
  73. package/lib/Socket/Client/types.d.ts +15 -15
  74. package/lib/Socket/Client/types.d.ts.map +1 -0
  75. package/lib/Socket/Client/types.js +8 -15
  76. package/lib/Socket/Client/types.js.map +1 -0
  77. package/lib/Socket/Client/websocket.d.ts +12 -12
  78. package/lib/Socket/Client/websocket.d.ts.map +1 -0
  79. package/lib/Socket/Client/websocket.js +29 -37
  80. package/lib/Socket/Client/websocket.js.map +1 -0
  81. package/lib/Socket/business.d.ts +208 -178
  82. package/lib/Socket/business.d.ts.map +1 -0
  83. package/lib/Socket/business.js +91 -127
  84. package/lib/Socket/business.js.map +1 -0
  85. package/lib/Socket/chats.d.ts +120 -93
  86. package/lib/Socket/chats.d.ts.map +1 -0
  87. package/lib/Socket/chats.js +727 -652
  88. package/lib/Socket/chats.js.map +1 -0
  89. package/lib/Socket/communities.d.ts +273 -0
  90. package/lib/Socket/communities.d.ts.map +1 -0
  91. package/lib/Socket/communities.js +431 -0
  92. package/lib/Socket/communities.js.map +1 -0
  93. package/lib/Socket/dugong.js +261 -0
  94. package/lib/Socket/dugong.js.bak +204 -0
  95. package/lib/Socket/groups.d.ts +143 -111
  96. package/lib/Socket/groups.d.ts.map +1 -0
  97. package/lib/Socket/groups.js +165 -177
  98. package/lib/Socket/groups.js.map +1 -0
  99. package/lib/Socket/index.d.ts +252 -183
  100. package/lib/Socket/index.d.ts.map +1 -0
  101. package/lib/Socket/index.js +38 -18
  102. package/lib/Socket/index.js.bak +44 -0
  103. package/lib/Socket/index.js.map +1 -0
  104. package/lib/Socket/messages-recv.d.ts +196 -167
  105. package/lib/Socket/messages-recv.d.ts.map +1 -0
  106. package/lib/Socket/messages-recv.js +1443 -1563
  107. package/lib/Socket/messages-recv.js.map +1 -0
  108. package/lib/Socket/messages-send.d.ts +192 -158
  109. package/lib/Socket/messages-send.d.ts.map +1 -0
  110. package/lib/Socket/messages-send.js +1102 -1208
  111. package/lib/Socket/messages-send.js.bak +1400 -0
  112. package/lib/Socket/messages-send.js.map +1 -0
  113. package/lib/Socket/mex.d.ts +3 -0
  114. package/lib/Socket/mex.d.ts.map +1 -0
  115. package/lib/Socket/mex.js +42 -0
  116. package/lib/Socket/mex.js.map +1 -0
  117. package/lib/Socket/newsletter.d.ts +163 -138
  118. package/lib/Socket/newsletter.d.ts.map +1 -0
  119. package/lib/Socket/newsletter.js +153 -249
  120. package/lib/Socket/newsletter.js.map +1 -0
  121. package/lib/Socket/socket.d.ts +50 -36
  122. package/lib/Socket/socket.d.ts.map +1 -0
  123. package/lib/Socket/socket.js +749 -820
  124. package/lib/Socket/socket.js.map +1 -0
  125. package/lib/Store/index.d.ts +4 -4
  126. package/lib/Store/index.d.ts.map +1 -0
  127. package/lib/Store/index.js +4 -24
  128. package/lib/Store/index.js.map +1 -0
  129. package/lib/Store/make-in-memory-store.d.ts +44 -104
  130. package/lib/Store/make-in-memory-store.d.ts.map +1 -0
  131. package/lib/Store/make-in-memory-store.js +199 -213
  132. package/lib/Store/make-in-memory-store.js.map +1 -0
  133. package/lib/Store/make-ordered-dictionary.d.ts +13 -12
  134. package/lib/Store/make-ordered-dictionary.d.ts.map +1 -0
  135. package/lib/Store/make-ordered-dictionary.js +38 -45
  136. package/lib/Store/make-ordered-dictionary.js.map +1 -0
  137. package/lib/Store/object-repository.d.ts +11 -10
  138. package/lib/Store/object-repository.d.ts.map +1 -0
  139. package/lib/Store/object-repository.js +9 -16
  140. package/lib/Store/object-repository.js.map +1 -0
  141. package/lib/Types/Auth.d.ts +93 -97
  142. package/lib/Types/Auth.d.ts.map +1 -0
  143. package/lib/Types/Auth.js +2 -3
  144. package/lib/Types/Auth.js.map +1 -0
  145. package/lib/Types/Bussines.d.ts +25 -0
  146. package/lib/Types/Bussines.d.ts.map +1 -0
  147. package/lib/Types/Bussines.js +2 -3
  148. package/lib/Types/Bussines.js.map +1 -0
  149. package/lib/Types/Call.d.ts +14 -13
  150. package/lib/Types/Call.d.ts.map +1 -0
  151. package/lib/Types/Call.js +2 -3
  152. package/lib/Types/Call.js.map +1 -0
  153. package/lib/Types/Chat.d.ts +78 -97
  154. package/lib/Types/Chat.d.ts.map +1 -0
  155. package/lib/Types/Chat.js +8 -9
  156. package/lib/Types/Chat.js.map +1 -0
  157. package/lib/Types/Contact.d.ts +12 -9
  158. package/lib/Types/Contact.d.ts.map +1 -0
  159. package/lib/Types/Contact.js +2 -3
  160. package/lib/Types/Contact.js.map +1 -0
  161. package/lib/Types/Events.d.ts +206 -176
  162. package/lib/Types/Events.d.ts.map +1 -0
  163. package/lib/Types/Events.js +2 -3
  164. package/lib/Types/Events.js.map +1 -0
  165. package/lib/Types/GroupMetadata.d.ts +53 -48
  166. package/lib/Types/GroupMetadata.d.ts.map +1 -0
  167. package/lib/Types/GroupMetadata.js +2 -3
  168. package/lib/Types/GroupMetadata.js.map +1 -0
  169. package/lib/Types/Label.d.ts +13 -14
  170. package/lib/Types/Label.d.ts.map +1 -0
  171. package/lib/Types/Label.js +24 -30
  172. package/lib/Types/Label.js.map +1 -0
  173. package/lib/Types/LabelAssociation.d.ts +15 -20
  174. package/lib/Types/LabelAssociation.d.ts.map +1 -0
  175. package/lib/Types/LabelAssociation.js +6 -12
  176. package/lib/Types/LabelAssociation.js.map +1 -0
  177. package/lib/Types/Message.d.ts +248 -412
  178. package/lib/Types/Message.d.ts.map +1 -0
  179. package/lib/Types/Message.js +17 -19
  180. package/lib/Types/Message.js.map +1 -0
  181. package/lib/Types/Mex.d.ts +141 -0
  182. package/lib/Types/Mex.d.ts.map +1 -0
  183. package/lib/Types/Mex.js +37 -0
  184. package/lib/Types/Mex.js.map +1 -0
  185. package/lib/Types/Product.d.ts +58 -71
  186. package/lib/Types/Product.d.ts.map +1 -0
  187. package/lib/Types/Product.js +2 -3
  188. package/lib/Types/Product.js.map +1 -0
  189. package/lib/Types/RichType.d.ts +3 -0
  190. package/lib/Types/RichType.d.ts.map +1 -0
  191. package/lib/Types/RichType.js +23 -0
  192. package/lib/Types/RichType.js.bak +23 -0
  193. package/lib/Types/RichType.js.map +1 -0
  194. package/lib/Types/Signal.d.ts +71 -82
  195. package/lib/Types/Signal.d.ts.map +1 -0
  196. package/lib/Types/Signal.js +2 -3
  197. package/lib/Types/Signal.js.map +1 -0
  198. package/lib/Types/Socket.d.ts +76 -81
  199. package/lib/Types/Socket.d.ts.map +1 -0
  200. package/lib/Types/Socket.js +3 -3
  201. package/lib/Types/Socket.js.map +1 -0
  202. package/lib/Types/State.d.ts +75 -19
  203. package/lib/Types/State.d.ts.map +1 -0
  204. package/lib/Types/State.js +56 -14
  205. package/lib/Types/State.js.map +1 -0
  206. package/lib/Types/USync.d.ts +8 -8
  207. package/lib/Types/USync.d.ts.map +1 -0
  208. package/lib/Types/USync.js +2 -3
  209. package/lib/Types/USync.js.map +1 -0
  210. package/lib/Types/index.d.ts +47 -62
  211. package/lib/Types/index.d.ts.map +1 -0
  212. package/lib/Types/index.js +26 -50
  213. package/lib/Types/index.js.map +1 -0
  214. package/lib/Utils/auth-utils.d.ts +13 -10
  215. package/lib/Utils/auth-utils.d.ts.map +1 -0
  216. package/lib/Utils/auth-utils.js +213 -454
  217. package/lib/Utils/auth-utils.js.map +1 -0
  218. package/lib/Utils/browser-utils.d.ts +4 -0
  219. package/lib/Utils/browser-utils.d.ts.map +1 -0
  220. package/lib/Utils/browser-utils.js +28 -0
  221. package/lib/Utils/browser-utils.js.map +1 -0
  222. package/lib/Utils/business.d.ts +14 -20
  223. package/lib/Utils/business.d.ts.map +1 -0
  224. package/lib/Utils/business.js +110 -134
  225. package/lib/Utils/business.js.map +1 -0
  226. package/lib/Utils/chat-utils.d.ts +88 -70
  227. package/lib/Utils/chat-utils.d.ts.map +1 -0
  228. package/lib/Utils/chat-utils.js +466 -403
  229. package/lib/Utils/chat-utils.js.map +1 -0
  230. package/lib/Utils/companion-reg-client-utils.d.ts +17 -0
  231. package/lib/Utils/companion-reg-client-utils.d.ts.map +1 -0
  232. package/lib/Utils/companion-reg-client-utils.js +35 -0
  233. package/lib/Utils/companion-reg-client-utils.js.map +1 -0
  234. package/lib/Utils/crypto.d.ts +27 -46
  235. package/lib/Utils/crypto.d.ts.map +1 -0
  236. package/lib/Utils/crypto.js +117 -188
  237. package/lib/Utils/crypto.js.map +1 -0
  238. package/lib/Utils/decode-wa-message.d.ts +58 -45
  239. package/lib/Utils/decode-wa-message.d.ts.map +1 -0
  240. package/lib/Utils/decode-wa-message.js +213 -303
  241. package/lib/Utils/decode-wa-message.js.map +1 -0
  242. package/lib/Utils/event-buffer.d.ts +14 -17
  243. package/lib/Utils/event-buffer.d.ts.map +1 -0
  244. package/lib/Utils/event-buffer.js +321 -296
  245. package/lib/Utils/event-buffer.js.map +1 -0
  246. package/lib/Utils/generics.d.ts +66 -92
  247. package/lib/Utils/generics.d.ts.map +1 -0
  248. package/lib/Utils/generics.js +270 -436
  249. package/lib/Utils/generics.js.map +1 -0
  250. package/lib/Utils/history.d.ts +24 -23
  251. package/lib/Utils/history.d.ts.map +1 -0
  252. package/lib/Utils/history.js +106 -76
  253. package/lib/Utils/history.js.map +1 -0
  254. package/lib/Utils/identity-change-handler.d.ts +44 -0
  255. package/lib/Utils/identity-change-handler.d.ts.map +1 -0
  256. package/lib/Utils/identity-change-handler.js +50 -0
  257. package/lib/Utils/identity-change-handler.js.map +1 -0
  258. package/lib/Utils/index.d.ts +24 -21
  259. package/lib/Utils/index.d.ts.map +1 -0
  260. package/lib/Utils/index.js +24 -41
  261. package/lib/Utils/index.js.map +1 -0
  262. package/lib/Utils/link-preview.d.ts +12 -14
  263. package/lib/Utils/link-preview.d.ts.map +1 -0
  264. package/lib/Utils/link-preview.js +40 -75
  265. package/lib/Utils/link-preview.js.map +1 -0
  266. package/lib/Utils/logger.d.ts +10 -11
  267. package/lib/Utils/logger.d.ts.map +1 -0
  268. package/lib/Utils/logger.js +3 -7
  269. package/lib/Utils/logger.js.map +1 -0
  270. package/lib/Utils/lt-hash.d.ts +8 -14
  271. package/lib/Utils/lt-hash.d.ts.map +1 -0
  272. package/lib/Utils/lt-hash.js +3 -53
  273. package/lib/Utils/lt-hash.js.map +1 -0
  274. package/lib/Utils/make-mutex.d.ts +7 -7
  275. package/lib/Utils/make-mutex.d.ts.map +1 -0
  276. package/lib/Utils/make-mutex.js +28 -44
  277. package/lib/Utils/make-mutex.js.map +1 -0
  278. package/lib/Utils/message-retry-manager.d.ts +115 -88
  279. package/lib/Utils/message-retry-manager.d.ts.map +1 -0
  280. package/lib/Utils/message-retry-manager.js +265 -160
  281. package/lib/Utils/message-retry-manager.js.map +1 -0
  282. package/lib/Utils/messages-media.d.ts +105 -107
  283. package/lib/Utils/messages-media.d.ts.map +1 -0
  284. package/lib/Utils/messages-media.js +548 -619
  285. package/lib/Utils/messages-media.js.bak +786 -0
  286. package/lib/Utils/messages-media.js.map +1 -0
  287. package/lib/Utils/messages.d.ts +52 -66
  288. package/lib/Utils/messages.d.ts.map +1 -0
  289. package/lib/Utils/messages.js +1730 -1558
  290. package/lib/Utils/messages.js.backup +1768 -0
  291. package/lib/Utils/messages.js.bak +1809 -0
  292. package/lib/Utils/messages.js.bak2 +893 -0
  293. package/lib/Utils/messages.js.bak3 +1183 -0
  294. package/lib/Utils/messages.js.map +1 -0
  295. package/lib/Utils/noise-handler.d.ts +18 -18
  296. package/lib/Utils/noise-handler.d.ts.map +1 -0
  297. package/lib/Utils/noise-handler.js +176 -130
  298. package/lib/Utils/noise-handler.js.map +1 -0
  299. package/lib/Utils/offline-node-processor.d.ts +17 -0
  300. package/lib/Utils/offline-node-processor.d.ts.map +1 -0
  301. package/lib/Utils/offline-node-processor.js +40 -0
  302. package/lib/Utils/offline-node-processor.js.map +1 -0
  303. package/lib/Utils/pre-key-manager.d.ts +28 -0
  304. package/lib/Utils/pre-key-manager.d.ts.map +1 -0
  305. package/lib/Utils/pre-key-manager.js +106 -0
  306. package/lib/Utils/pre-key-manager.js.map +1 -0
  307. package/lib/Utils/process-message.d.ts +43 -32
  308. package/lib/Utils/process-message.d.ts.map +1 -0
  309. package/lib/Utils/process-message.js +484 -282
  310. package/lib/Utils/process-message.js.map +1 -0
  311. package/lib/Utils/reporting-utils.d.ts +11 -0
  312. package/lib/Utils/reporting-utils.d.ts.map +1 -0
  313. package/lib/Utils/reporting-utils.js +258 -0
  314. package/lib/Utils/reporting-utils.js.map +1 -0
  315. package/lib/Utils/rich-message-utils.d.ts +49 -0
  316. package/lib/Utils/rich-message-utils.d.ts.map +1 -0
  317. package/lib/Utils/rich-message-utils.js +1220 -724
  318. package/lib/Utils/rich-message-utils.js.backup +706 -0
  319. package/lib/Utils/rich-message-utils.js.bak +246 -0
  320. package/lib/Utils/rich-message-utils.js.map +1 -0
  321. package/lib/Utils/rich-message-utils.js.original +1332 -0
  322. package/lib/Utils/signal.d.ts +37 -32
  323. package/lib/Utils/signal.d.ts.map +1 -0
  324. package/lib/Utils/signal.js +140 -105
  325. package/lib/Utils/signal.js.map +1 -0
  326. package/lib/Utils/stanza-ack.d.ts +11 -0
  327. package/lib/Utils/stanza-ack.d.ts.map +1 -0
  328. package/lib/Utils/stanza-ack.js +38 -0
  329. package/lib/Utils/stanza-ack.js.map +1 -0
  330. package/lib/Utils/sync-action-utils.d.ts +19 -0
  331. package/lib/Utils/sync-action-utils.d.ts.map +1 -0
  332. package/lib/Utils/sync-action-utils.js +49 -0
  333. package/lib/Utils/sync-action-utils.js.map +1 -0
  334. package/lib/Utils/tc-token-utils.d.ts +37 -0
  335. package/lib/Utils/tc-token-utils.d.ts.map +1 -0
  336. package/lib/Utils/tc-token-utils.js +163 -0
  337. package/lib/Utils/tc-token-utils.js.map +1 -0
  338. package/lib/Utils/use-multi-file-auth-state.d.ts +5 -5
  339. package/lib/Utils/use-multi-file-auth-state.d.ts.map +1 -0
  340. package/lib/Utils/use-multi-file-auth-state.js +70 -120
  341. package/lib/Utils/use-multi-file-auth-state.js.map +1 -0
  342. package/lib/Utils/use-single-file-auth-state.d.ts +11 -13
  343. package/lib/Utils/use-single-file-auth-state.d.ts.map +1 -0
  344. package/lib/Utils/use-single-file-auth-state.js +92 -66
  345. package/lib/Utils/use-single-file-auth-state.js.map +1 -0
  346. package/lib/Utils/use-sqlite-auth-state.d.ts +11 -0
  347. package/lib/Utils/use-sqlite-auth-state.d.ts.map +1 -0
  348. package/lib/Utils/use-sqlite-auth-state.js +109 -0
  349. package/lib/Utils/use-sqlite-auth-state.js.map +1 -0
  350. package/lib/Utils/validate-connection.d.ts +11 -13
  351. package/lib/Utils/validate-connection.d.ts.map +1 -0
  352. package/lib/Utils/validate-connection.js +128 -113
  353. package/lib/Utils/validate-connection.js.map +1 -0
  354. package/lib/WABinary/constants.d.ts +25 -27
  355. package/lib/WABinary/constants.d.ts.map +1 -0
  356. package/lib/WABinary/constants.js +1451 -1292
  357. package/lib/WABinary/constants.js.bak +1373 -0
  358. package/lib/WABinary/constants.js.map +1 -0
  359. package/lib/WABinary/decode.d.ts +7 -9
  360. package/lib/WABinary/decode.d.ts.map +1 -0
  361. package/lib/WABinary/decode.js +163 -189
  362. package/lib/WABinary/decode.js.map +1 -0
  363. package/lib/WABinary/encode.d.ts +3 -3
  364. package/lib/WABinary/encode.d.ts.map +1 -0
  365. package/lib/WABinary/encode.js +110 -155
  366. package/lib/WABinary/encode.js.map +1 -0
  367. package/lib/WABinary/generic-utils.d.ts +14 -27
  368. package/lib/WABinary/generic-utils.d.ts.map +1 -0
  369. package/lib/WABinary/generic-utils.js +177 -105
  370. package/lib/WABinary/generic-utils.js.map +1 -0
  371. package/lib/WABinary/index.d.ts +6 -5
  372. package/lib/WABinary/index.d.ts.map +1 -0
  373. package/lib/WABinary/index.js +6 -25
  374. package/lib/WABinary/index.js.map +1 -0
  375. package/lib/WABinary/jid-utils.d.ts +41 -51
  376. package/lib/WABinary/jid-utils.d.ts.map +1 -0
  377. package/lib/WABinary/jid-utils.js +83 -120
  378. package/lib/WABinary/jid-utils.js.map +1 -0
  379. package/lib/WABinary/types.d.ts +10 -13
  380. package/lib/WABinary/types.d.ts.map +1 -0
  381. package/lib/WABinary/types.js +2 -3
  382. package/lib/WABinary/types.js.map +1 -0
  383. package/lib/WAM/BinaryInfo.d.ts +8 -15
  384. package/lib/WAM/BinaryInfo.d.ts.map +1 -0
  385. package/lib/WAM/BinaryInfo.js +7 -14
  386. package/lib/WAM/BinaryInfo.js.map +1 -0
  387. package/lib/WAM/constants.d.ts +30 -37
  388. package/lib/WAM/constants.d.ts.map +1 -0
  389. package/lib/WAM/constants.js +19193 -11711
  390. package/lib/WAM/constants.js.map +1 -0
  391. package/lib/WAM/encode.d.ts +3 -3
  392. package/lib/WAM/encode.d.ts.map +1 -0
  393. package/lib/WAM/encode.js +95 -109
  394. package/lib/WAM/encode.js.map +1 -0
  395. package/lib/WAM/index.d.ts +4 -3
  396. package/lib/WAM/index.d.ts.map +1 -0
  397. package/lib/WAM/index.js +4 -23
  398. package/lib/WAM/index.js.map +1 -0
  399. package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +9 -9
  400. package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts.map +1 -0
  401. package/lib/WAUSync/Protocols/USyncContactProtocol.js +37 -21
  402. package/lib/WAUSync/Protocols/USyncContactProtocol.js.map +1 -0
  403. package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +19 -22
  404. package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts.map +1 -0
  405. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +18 -26
  406. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js.map +1 -0
  407. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +11 -12
  408. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts.map +1 -0
  409. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +12 -20
  410. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js.map +1 -0
  411. package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +11 -12
  412. package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts.map +1 -0
  413. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +16 -24
  414. package/lib/WAUSync/Protocols/USyncStatusProtocol.js.map +1 -0
  415. package/lib/WAUSync/Protocols/USyncUsernameProtocol.d.ts +10 -0
  416. package/lib/WAUSync/Protocols/USyncUsernameProtocol.d.ts.map +1 -0
  417. package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +25 -0
  418. package/lib/WAUSync/Protocols/USyncUsernameProtocol.js.map +1 -0
  419. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts +26 -0
  420. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts.map +1 -0
  421. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +51 -0
  422. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js.map +1 -0
  423. package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts +10 -0
  424. package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts.map +1 -0
  425. package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +29 -0
  426. package/lib/WAUSync/Protocols/UsyncLIDProtocol.js.map +1 -0
  427. package/lib/WAUSync/Protocols/index.d.ts +6 -6
  428. package/lib/WAUSync/Protocols/index.d.ts.map +1 -0
  429. package/lib/WAUSync/Protocols/index.js +6 -26
  430. package/lib/WAUSync/Protocols/index.js.map +1 -0
  431. package/lib/WAUSync/USyncQuery.d.ts +27 -28
  432. package/lib/WAUSync/USyncQuery.d.ts.map +1 -0
  433. package/lib/WAUSync/USyncQuery.js +68 -62
  434. package/lib/WAUSync/USyncQuery.js.map +1 -0
  435. package/lib/WAUSync/USyncUser.d.ts +15 -10
  436. package/lib/WAUSync/USyncUser.d.ts.map +1 -0
  437. package/lib/WAUSync/USyncUser.js +20 -19
  438. package/lib/WAUSync/USyncUser.js.map +1 -0
  439. package/lib/WAUSync/index.d.ts +4 -3
  440. package/lib/WAUSync/index.d.ts.map +1 -0
  441. package/lib/WAUSync/index.js +4 -23
  442. package/lib/WAUSync/index.js.map +1 -0
  443. package/lib/index.d.ts +11 -12
  444. package/lib/index.d.ts.map +1 -0
  445. package/lib/index.js +12 -39
  446. package/lib/index.js.map +1 -0
  447. package/package.json +86 -42
@@ -1,80 +1,87 @@
1
- "use strict"
2
-
3
- var __importDefault = (this && this.__importDefault) || function (mod) {
4
- return (mod && mod.__esModule) ? mod : { "default": mod }
5
- }
6
-
7
- Object.defineProperty(exports, "__esModule", { value: true })
8
-
9
- const node_cache_1 = __importDefault(require("@cacheable/node-cache"))
10
- const boom_1 = require("@hapi/boom")
11
- const WAProto_1 = require("../../WAProto")
12
- const Defaults_1 = require("../Defaults")
13
- const Types_1 = require("../Types")
14
- const Utils_1 = require("../Utils")
15
- const make_mutex_1 = require("../Utils/make-mutex")
16
- const WABinary_1 = require("../WABinary")
17
- const WAUSync_1 = require("../WAUSync")
18
- const socket_1 = require("./socket")
19
- const MAX_SYNC_ATTEMPTS = 2
20
-
21
- const makeChatsSocket = (config) => {
22
- const { logger, markOnlineOnConnect, fireInitQueries, appStateMacVerification, shouldIgnoreJid, shouldSyncHistoryMessage, } = config
23
- const sock = socket_1.makeSocket(config)
24
- const { ev, ws, authState, generateMessageTag, sendNode, query, signalRepository, onUnexpectedError, groupFetchAllParticipating } = sock
25
-
26
- let privacySettings
27
- let syncState = Types_1.SyncState.Connecting
28
-
29
- /** this mutex ensures that the notifications (receipts, messages etc.) are processed in order */
30
- const processingMutex = make_mutex_1.makeMutex()
31
-
32
- // Timeout for AwaitingInitialSync State
33
- let awaitingSyncTimeout
34
-
35
- const placeholderResendCache = config.placeholderResendCache || new node_cache_1.default({
36
- stdTTL: Defaults_1.DEFAULT_CACHE_TTLS.MSG_RETRY,
37
- useClones: false
38
- })
39
-
40
- if (!config.placeholderResendCache) {
41
- config.placeholderResendCache = placeholderResendCache
42
- }
43
-
1
+ import NodeCache from '@cacheable/node-cache';
2
+ import { Boom } from '@hapi/boom';
3
+ import { proto } from '../../WAProto/index.js';
4
+ import { DEFAULT_CACHE_TTLS, HISTORY_SYNC_PAUSED_TIMEOUT_MS, PROCESSABLE_HISTORY_TYPES } from '../Defaults/index.js';
5
+ import { ALL_WA_PATCH_NAMES } from '../Types/index.js';
6
+ import { SyncState } from '../Types/State.js';
7
+ import { chatModificationToAppPatch, decodePatches, decodeSyncdSnapshot, encodeSyncdPatch, ensureLTHashStateVersion, extractSyncdPatches, generateProfilePicture, getHistoryMsg, isAppStateSyncIrrecoverable, isMissingKeyError, MAX_SYNC_ATTEMPTS, newLTHashState, processSyncAction } from '../Utils/index.js';
8
+ import { makeMutex } from '../Utils/make-mutex.js';
9
+ import processMessage from '../Utils/process-message.js';
10
+ import { buildTcTokenFromJid } from '../Utils/tc-token-utils.js';
11
+ import { getBinaryNodeChild, getBinaryNodeChildren, isHostedLidUser, isHostedPnUser, isLidUser, isPnUser, jidDecode, jidNormalizedUser, reduceBinaryNodeToDictionary, S_WHATSAPP_NET } from '../WABinary/index.js';
12
+ import { USyncQuery, USyncUser } from '../WAUSync/index.js';
13
+ import { makeSocket } from './socket.js';
14
+ export const makeChatsSocket = (config) => {
15
+ const { logger, markOnlineOnConnect, fireInitQueries, appStateMacVerification, shouldIgnoreJid, shouldSyncHistoryMessage, getMessage } = config;
16
+ const sock = makeSocket(config);
17
+ const { ev, ws, authState, generateMessageTag, sendNode, query, signalRepository, onUnexpectedError, sendUnifiedSession, registerSocketEndHandler } = sock;
18
+ const getLIDForPN = signalRepository.lidMapping.getLIDForPN.bind(signalRepository.lidMapping);
19
+ let privacySettings;
20
+ /** Server-assigned AB props for protocol behavior. */
21
+ const serverProps = {
22
+ /** AB prop 10518: gate tctoken on 1:1 messages. Default true (safe: avoids 463). */
23
+ privacyTokenOn1to1: true,
24
+ /** AB prop 9666: gate tctoken on profile picture IQs. WA Web default: true. */
25
+ profilePicPrivacyToken: true,
26
+ /** AB prop 14303: issue tctokens to LID instead of PN. WA Web default: false. */
27
+ lidTrustedTokenIssueToLid: false
28
+ };
29
+ let syncState = SyncState.Connecting;
30
+ /** this mutex ensures that messages are processed in order */
31
+ const messageMutex = makeMutex();
32
+ /** this mutex ensures that receipts are processed in order */
33
+ const receiptMutex = makeMutex();
34
+ /** this mutex ensures that app state patches are processed in order */
35
+ const appStatePatchMutex = makeMutex();
36
+ /** this mutex ensures that notifications are processed in order */
37
+ const notificationMutex = makeMutex();
38
+ // Timeout for AwaitingInitialSync state
39
+ let awaitingSyncTimeout;
40
+ // In-memory history sync completion tracking (resets on reconnection)
41
+ const historySyncStatus = {
42
+ initialBootstrapComplete: false,
43
+ recentSyncComplete: false
44
+ };
45
+ let historySyncPausedTimeout;
46
+ // Collections blocked on missing app state sync keys (mirrors WA Web's "Blocked" state).
47
+ // When a key arrives via APP_STATE_SYNC_KEY_SHARE, these are re-synced.
48
+ const blockedCollections = new Set();
49
+ const placeholderResendCache = config.placeholderResendCache ||
50
+ new NodeCache({
51
+ stdTTL: DEFAULT_CACHE_TTLS.MSG_RETRY, // 1 hour
52
+ useClones: false
53
+ });
44
54
  /** helper function to fetch the given app state sync key */
45
55
  const getAppStateSyncKey = async (keyId) => {
46
- const { [keyId]: key } = await authState.keys.get('app-state-sync-key', [keyId])
47
- return key
48
- }
49
-
56
+ const { [keyId]: key } = await authState.keys.get('app-state-sync-key', [keyId]);
57
+ return key;
58
+ };
50
59
  const fetchPrivacySettings = async (force = false) => {
51
60
  if (!privacySettings || force) {
52
61
  const { content } = await query({
53
62
  tag: 'iq',
54
63
  attrs: {
55
64
  xmlns: 'privacy',
56
- to: WABinary_1.S_WHATSAPP_NET,
65
+ to: S_WHATSAPP_NET,
57
66
  type: 'get'
58
67
  },
59
- content: [
60
- { tag: 'privacy', attrs: {} }
61
- ]
62
- })
63
- privacySettings = WABinary_1.reduceBinaryNodeToDictionary(content?.[0], 'category')
68
+ content: [{ tag: 'privacy', attrs: {} }]
69
+ });
70
+ privacySettings = reduceBinaryNodeToDictionary(content?.[0], 'category');
64
71
  }
65
- return privacySettings
66
- }
67
-
72
+ return privacySettings;
73
+ };
68
74
  /** helper function to run a privacy IQ query */
69
75
  const privacyQuery = async (name, value) => {
70
76
  await query({
71
77
  tag: 'iq',
72
78
  attrs: {
73
79
  xmlns: 'privacy',
74
- to: WABinary_1.S_WHATSAPP_NET,
80
+ to: S_WHATSAPP_NET,
75
81
  type: 'set'
76
82
  },
77
- content: [{
83
+ content: [
84
+ {
78
85
  tag: 'privacy',
79
86
  attrs: {},
80
87
  content: [
@@ -83,172 +90,123 @@ const makeChatsSocket = (config) => {
83
90
  attrs: { name, value }
84
91
  }
85
92
  ]
86
- }]
87
- })
88
- }
89
-
93
+ }
94
+ ]
95
+ });
96
+ };
90
97
  const updateMessagesPrivacy = async (value) => {
91
- await privacyQuery('messages', value)
92
- }
93
-
98
+ await privacyQuery('messages', value);
99
+ };
94
100
  const updateCallPrivacy = async (value) => {
95
- await privacyQuery('calladd', value)
96
- }
97
-
101
+ await privacyQuery('calladd', value);
102
+ };
98
103
  const updateLastSeenPrivacy = async (value) => {
99
- await privacyQuery('last', value)
100
- }
101
-
104
+ await privacyQuery('last', value);
105
+ };
102
106
  const updateOnlinePrivacy = async (value) => {
103
- await privacyQuery('online', value)
104
- }
105
-
107
+ await privacyQuery('online', value);
108
+ };
106
109
  const updateProfilePicturePrivacy = async (value) => {
107
- await privacyQuery('profile', value)
108
- }
109
-
110
+ await privacyQuery('profile', value);
111
+ };
110
112
  const updateStatusPrivacy = async (value) => {
111
- await privacyQuery('status', value)
112
- }
113
-
113
+ await privacyQuery('status', value);
114
+ };
114
115
  const updateReadReceiptsPrivacy = async (value) => {
115
- await privacyQuery('readreceipts', value)
116
- }
117
-
116
+ await privacyQuery('readreceipts', value);
117
+ };
118
118
  const updateGroupsAddPrivacy = async (value) => {
119
- await privacyQuery('groupadd', value)
120
- }
121
-
119
+ await privacyQuery('groupadd', value);
120
+ };
122
121
  const updateDefaultDisappearingMode = async (duration) => {
123
122
  await query({
124
123
  tag: 'iq',
125
124
  attrs: {
126
125
  xmlns: 'disappearing_mode',
127
- to: WABinary_1.S_WHATSAPP_NET,
126
+ to: S_WHATSAPP_NET,
128
127
  type: 'set'
129
128
  },
130
- content: [{
129
+ content: [
130
+ {
131
131
  tag: 'disappearing_mode',
132
132
  attrs: {
133
133
  duration: duration.toString()
134
134
  }
135
- }]
136
- })
137
- }
138
-
135
+ }
136
+ ]
137
+ });
138
+ };
139
139
  const getBotListV2 = async () => {
140
- const resp = await query({
141
- tag: 'iq',
142
- attrs: {
143
- xmlns: 'bot',
144
- to: WABinary_1.S_WHATSAPP_NET,
145
- type: 'get'
146
- },
147
- content: [{
148
- tag: 'bot',
149
- attrs: {
150
- v: '2'
151
- }
152
- }]
153
- })
154
-
155
- const botNode = WABinary_1.getBinaryNodeChild(resp, 'bot')
156
-
157
- const botList = []
158
-
159
- for(const section of WABinary_1.getBinaryNodeChildren(botNode, 'section')) {
160
- if(section.attrs.type === 'all') {
161
- for(const bot of WABinary_1.getBinaryNodeChildren(section, 'bot')) {
162
- botList.push({
163
- jid: bot.attrs.jid,
164
- personaId: bot.attrs['persona_id']
165
- })
166
- }
167
- }
168
- }
169
- return botList
170
- }
171
-
172
- const getLidUser = async (jid) => {
173
- if (!jid) {
174
- throw new boom_1.Boom('Please input a jid user')
175
- }
176
-
177
- if (!WABinary_1.isJidUser(jid)) {
178
- throw new boom_1.Boom('Invalid JID: Not a user JID!')
179
- }
180
-
181
- const targetJid = WABinary_1.jidNormalizedUser(jid)
182
-
183
- const usyncQuery = new WAUSync_1.USyncQuery()
184
- usyncQuery.protocols.push({
185
- name: 'lid',
186
- getQueryElement: () => ({
187
- tag: 'lid',
188
- attrs: {},
189
- content: undefined
190
- }),
191
- getUserElement: () => null,
192
- parser: (node) => node.attrs.val
193
- })
194
- usyncQuery.users.push({
195
- id: targetJid
196
- })
197
-
198
- const result = await sock.executeUSyncQuery(usyncQuery)
199
-
200
- if (result) {
201
- return result.list
140
+ const resp = await query({
141
+ tag: 'iq',
142
+ attrs: {
143
+ xmlns: 'bot',
144
+ to: S_WHATSAPP_NET,
145
+ type: 'get'
146
+ },
147
+ content: [
148
+ {
149
+ tag: 'bot',
150
+ attrs: {
151
+ v: '2'
152
+ }
153
+ }
154
+ ]
155
+ });
156
+ const botNode = getBinaryNodeChild(resp, 'bot');
157
+ const botList = [];
158
+ for (const section of getBinaryNodeChildren(botNode, 'section')) {
159
+ if (section.attrs.type === 'all') {
160
+ for (const bot of getBinaryNodeChildren(section, 'bot')) {
161
+ botList.push({
162
+ jid: bot.attrs.jid,
163
+ personaId: bot.attrs['persona_id']
164
+ });
165
+ }
166
+ }
202
167
  }
203
- }
204
-
168
+ return botList;
169
+ };
205
170
  const fetchStatus = async (...jids) => {
206
- const usyncQuery = new WAUSync_1.USyncQuery().withStatusProtocol()
207
-
171
+ const usyncQuery = new USyncQuery().withStatusProtocol();
208
172
  for (const jid of jids) {
209
- usyncQuery.withUser(new WAUSync_1.USyncUser().withId(jid))
173
+ usyncQuery.withUser(new USyncUser().withId(jid));
210
174
  }
211
-
212
- const result = await sock.executeUSyncQuery(usyncQuery)
213
-
175
+ const result = await sock.executeUSyncQuery(usyncQuery);
214
176
  if (result) {
215
- return result.list
177
+ return result.list;
216
178
  }
217
- }
218
- const fetchDisappearingDuration = async (...jids) => {
219
- const usyncQuery = new WAUSync_1.USyncQuery().withDisappearingModeProtocol()
220
-
179
+ };
180
+ const fetchDisappearingDuration = async (...jids) => {
181
+ const usyncQuery = new USyncQuery().withDisappearingModeProtocol();
221
182
  for (const jid of jids) {
222
- usyncQuery.withUser(new WAUSync_1.USyncUser().withId(jid))
183
+ usyncQuery.withUser(new USyncUser().withId(jid));
223
184
  }
224
-
225
- const result = await sock.executeUSyncQuery(usyncQuery)
185
+ const result = await sock.executeUSyncQuery(usyncQuery);
226
186
  if (result) {
227
- return result.list
187
+ return result.list;
228
188
  }
229
- }
230
-
189
+ };
231
190
  /** update the profile picture for yourself or a group */
232
- const updateProfilePicture = async (jid, content) => {
233
- let targetJid
234
-
191
+ const updateProfilePicture = async (jid, content, dimensions) => {
192
+ let targetJid;
235
193
  if (!jid) {
236
- throw new boom_1.Boom('Illegal no-jid profile update. Please specify either your ID or the ID of the chat you wish to update')
194
+ throw new Boom('Illegal no-jid profile update. Please specify either your ID or the ID of the chat you wish to update');
195
+ }
196
+ if (jidNormalizedUser(jid) !== jidNormalizedUser(authState.creds.me.id)) {
197
+ targetJid = jidNormalizedUser(jid); // in case it is someone other than us
237
198
  }
238
-
239
- if (WABinary_1.jidNormalizedUser(jid) !== WABinary_1.jidNormalizedUser(authState.creds.me.id)) {
240
- targetJid = WABinary_1.jidNormalizedUser(jid) // in case it is someone other than us
199
+ else {
200
+ targetJid = undefined;
241
201
  }
242
-
243
- const { img } = await Utils_1.generateProfilePicture(content)
244
-
202
+ const { img } = await generateProfilePicture(content, dimensions);
245
203
  await query({
246
204
  tag: 'iq',
247
205
  attrs: {
248
- target: targetJid,
249
- to: WABinary_1.S_WHATSAPP_NET,
206
+ to: S_WHATSAPP_NET,
250
207
  type: 'set',
251
- xmlns: 'w:profile:picture'
208
+ xmlns: 'w:profile:picture',
209
+ ...(targetJid ? { target: targetJid } : {})
252
210
  },
253
211
  content: [
254
212
  {
@@ -257,38 +215,36 @@ const makeChatsSocket = (config) => {
257
215
  content: img
258
216
  }
259
217
  ]
260
- })
261
- }
262
-
218
+ });
219
+ };
263
220
  /** remove the profile picture for yourself or a group */
264
221
  const removeProfilePicture = async (jid) => {
265
- let targetJid
266
-
222
+ let targetJid;
267
223
  if (!jid) {
268
- throw new boom_1.Boom('Illegal no-jid profile update. Please specify either your ID or the ID of the chat you wish to update')
224
+ throw new Boom('Illegal no-jid profile update. Please specify either your ID or the ID of the chat you wish to update');
269
225
  }
270
-
271
- if (WABinary_1.jidNormalizedUser(jid) !== WABinary_1.jidNormalizedUser(authState.creds.me.id)) {
272
- targetJid = WABinary_1.jidNormalizedUser(jid) // in case it is someone other than us
226
+ if (jidNormalizedUser(jid) !== jidNormalizedUser(authState.creds.me.id)) {
227
+ targetJid = jidNormalizedUser(jid); // in case it is someone other than us
228
+ }
229
+ else {
230
+ targetJid = undefined;
273
231
  }
274
-
275
232
  await query({
276
233
  tag: 'iq',
277
234
  attrs: {
278
- target: targetJid,
279
- to: WABinary_1.S_WHATSAPP_NET,
235
+ to: S_WHATSAPP_NET,
280
236
  type: 'set',
281
- xmlns: 'w:profile:picture'
237
+ xmlns: 'w:profile:picture',
238
+ ...(targetJid ? { target: targetJid } : {})
282
239
  }
283
- })
284
- }
285
-
240
+ });
241
+ };
286
242
  /** update the profile status for yourself */
287
243
  const updateProfileStatus = async (status) => {
288
244
  await query({
289
245
  tag: 'iq',
290
246
  attrs: {
291
- to: WABinary_1.S_WHATSAPP_NET,
247
+ to: S_WHATSAPP_NET,
292
248
  type: 'set',
293
249
  xmlns: 'status'
294
250
  },
@@ -299,48 +255,75 @@ const makeChatsSocket = (config) => {
299
255
  content: Buffer.from(status, 'utf-8')
300
256
  }
301
257
  ]
302
- })
303
- }
304
-
258
+ });
259
+ };
305
260
  const updateProfileName = async (name) => {
306
- await chatModify({ pushNameSetting: name }, '')
307
- }
308
-
261
+ await chatModify({ pushNameSetting: name }, '');
262
+ };
309
263
  const fetchBlocklist = async () => {
310
264
  const result = await query({
311
265
  tag: 'iq',
312
266
  attrs: {
313
267
  xmlns: 'blocklist',
314
- to: WABinary_1.S_WHATSAPP_NET,
268
+ to: S_WHATSAPP_NET,
315
269
  type: 'get'
316
270
  }
317
- })
318
-
319
- const listNode = WABinary_1.getBinaryNodeChild(result, 'list')
320
-
321
- return WABinary_1.getBinaryNodeChildren(listNode, 'item').map((n) => n.attrs.jid)
322
- }
323
-
271
+ });
272
+ const listNode = getBinaryNodeChild(result, 'list');
273
+ return getBinaryNodeChildren(listNode, 'item').map(n => n.attrs.jid);
274
+ };
324
275
  const updateBlockStatus = async (jid, action) => {
276
+ const normalizedJid = jidNormalizedUser(jid);
277
+ let lid;
278
+ let pn_jid;
279
+ if (isLidUser(normalizedJid) || isHostedLidUser(normalizedJid)) {
280
+ lid = normalizedJid;
281
+ if (action === 'block') {
282
+ const pn = await signalRepository.lidMapping.getPNForLID(normalizedJid);
283
+ if (!pn) {
284
+ throw new Boom(`Unable to resolve PN JID for LID: ${jid}`, { statusCode: 400 });
285
+ }
286
+ pn_jid = jidNormalizedUser(pn);
287
+ }
288
+ }
289
+ else if (isPnUser(normalizedJid) || isHostedPnUser(normalizedJid)) {
290
+ const mapped = await signalRepository.lidMapping.getLIDForPN(normalizedJid);
291
+ if (!mapped) {
292
+ throw new Boom(`Unable to resolve LID for PN JID: ${jid}`, { statusCode: 400 });
293
+ }
294
+ lid = mapped;
295
+ if (action === 'block') {
296
+ pn_jid = jidNormalizedUser(normalizedJid);
297
+ }
298
+ }
299
+ else {
300
+ throw new Boom(`Invalid jid: ${jid}`, { statusCode: 400 });
301
+ }
302
+ const itemAttrs = {
303
+ action,
304
+ jid: lid
305
+ };
306
+ if (action === 'block') {
307
+ if (!pn_jid) {
308
+ throw new Boom(`pn_jid required for block: ${jid}`, { statusCode: 400 });
309
+ }
310
+ itemAttrs.pn_jid = pn_jid;
311
+ }
325
312
  await query({
326
313
  tag: 'iq',
327
314
  attrs: {
328
315
  xmlns: 'blocklist',
329
- to: WABinary_1.S_WHATSAPP_NET,
316
+ to: S_WHATSAPP_NET,
330
317
  type: 'set'
331
318
  },
332
319
  content: [
333
320
  {
334
321
  tag: 'item',
335
- attrs: {
336
- action,
337
- jid
338
- }
322
+ attrs: itemAttrs
339
323
  }
340
324
  ]
341
- })
342
- }
343
-
325
+ });
326
+ };
344
327
  const getBusinessProfile = async (jid) => {
345
328
  const results = await query({
346
329
  tag: 'iq',
@@ -349,121 +332,133 @@ const makeChatsSocket = (config) => {
349
332
  xmlns: 'w:biz',
350
333
  type: 'get'
351
334
  },
352
- content: [{
335
+ content: [
336
+ {
353
337
  tag: 'business_profile',
354
338
  attrs: { v: '244' },
355
- content: [{
339
+ content: [
340
+ {
356
341
  tag: 'profile',
357
342
  attrs: { jid }
358
- }]
359
- }]
360
- })
361
-
362
- const profileNode = WABinary_1.getBinaryNodeChild(results, 'business_profile')
363
-
364
- const profiles = WABinary_1.getBinaryNodeChild(profileNode, 'profile')
365
-
343
+ }
344
+ ]
345
+ }
346
+ ]
347
+ });
348
+ const profileNode = getBinaryNodeChild(results, 'business_profile');
349
+ const profiles = getBinaryNodeChild(profileNode, 'profile');
366
350
  if (profiles) {
367
- const address = WABinary_1.getBinaryNodeChild(profiles, 'address')
368
- const description = WABinary_1.getBinaryNodeChild(profiles, 'description')
369
- const website = WABinary_1.getBinaryNodeChild(profiles, 'website')
370
- const email = WABinary_1.getBinaryNodeChild(profiles, 'email')
371
- const category = WABinary_1.getBinaryNodeChild(WABinary_1.getBinaryNodeChild(profiles, 'categories'), 'category')
372
- const businessHours = WABinary_1.getBinaryNodeChild(profiles, 'business_hours')
351
+ const address = getBinaryNodeChild(profiles, 'address');
352
+ const description = getBinaryNodeChild(profiles, 'description');
353
+ const website = getBinaryNodeChild(profiles, 'website');
354
+ const email = getBinaryNodeChild(profiles, 'email');
355
+ const category = getBinaryNodeChild(getBinaryNodeChild(profiles, 'categories'), 'category');
356
+ const businessHours = getBinaryNodeChild(profiles, 'business_hours');
373
357
  const businessHoursConfig = businessHours
374
- ? WABinary_1.getBinaryNodeChildren(businessHours, 'business_hours_config')
375
- : undefined
376
- const websiteStr = website?.content?.toString()
377
-
358
+ ? getBinaryNodeChildren(businessHours, 'business_hours_config')
359
+ : undefined;
360
+ const websiteStr = website?.content?.toString();
378
361
  return {
379
- wid: profiles?.attrs?.jid,
362
+ wid: profiles.attrs?.jid,
380
363
  address: address?.content?.toString(),
381
364
  description: description?.content?.toString() || '',
382
365
  website: websiteStr ? [websiteStr] : [],
383
366
  email: email?.content?.toString(),
384
367
  category: category?.content?.toString(),
385
- 'business_hours': {
368
+ business_hours: {
386
369
  timezone: businessHours?.attrs?.timezone,
387
- 'business_config': businessHoursConfig?.map(({ attrs }) => attrs)
370
+ business_config: businessHoursConfig?.map(({ attrs }) => attrs)
388
371
  }
389
- }
372
+ };
390
373
  }
391
- }
392
-
374
+ };
393
375
  const cleanDirtyBits = async (type, fromTimestamp) => {
394
- logger.info({ fromTimestamp }, 'clean dirty bits ' + type)
376
+ logger.info({ fromTimestamp }, 'clean dirty bits ' + type);
395
377
  await sendNode({
396
378
  tag: 'iq',
397
379
  attrs: {
398
- to: WABinary_1.S_WHATSAPP_NET,
380
+ to: S_WHATSAPP_NET,
399
381
  type: 'set',
400
382
  xmlns: 'urn:xmpp:whatsapp:dirty',
401
- id: generateMessageTag(),
383
+ id: generateMessageTag()
402
384
  },
403
385
  content: [
404
386
  {
405
387
  tag: 'clean',
406
388
  attrs: {
407
389
  type,
408
- ...(fromTimestamp ? { timestamp: fromTimestamp.toString() } : null),
390
+ ...(fromTimestamp ? { timestamp: fromTimestamp.toString() } : null)
409
391
  }
410
392
  }
411
393
  ]
412
- })
413
- }
414
-
394
+ });
395
+ };
415
396
  const newAppStateChunkHandler = (isInitialSync) => {
416
397
  return {
417
398
  onMutation(mutation) {
418
- Utils_1.processSyncAction(mutation, ev, authState.creds.me, isInitialSync ? { accountSettings: authState.creds.accountSettings } : undefined, logger)
399
+ processSyncAction(mutation, ev, authState.creds.me, isInitialSync ? { accountSettings: authState.creds.accountSettings } : undefined, logger);
419
400
  }
420
- }
421
- }
422
-
401
+ };
402
+ };
423
403
  const resyncAppState = ev.createBufferedFunction(async (collections, isInitialSync) => {
404
+ const appStateSyncKeyCache = new Map();
405
+ const getCachedAppStateSyncKey = async (keyId) => {
406
+ if (appStateSyncKeyCache.has(keyId)) {
407
+ return appStateSyncKeyCache.get(keyId) ?? undefined;
408
+ }
409
+ const key = await getAppStateSyncKey(keyId);
410
+ appStateSyncKeyCache.set(keyId, key ?? null);
411
+ return key;
412
+ };
424
413
  // we use this to determine which events to fire
425
414
  // otherwise when we resync from scratch -- all notifications will fire
426
- const initialVersionMap = {}
427
- const globalMutationMap = {}
415
+ const initialVersionMap = {};
416
+ const globalMutationMap = {};
428
417
  await authState.keys.transaction(async () => {
429
- const collectionsToHandle = new Set(collections)
418
+ const collectionsToHandle = new Set(collections);
430
419
  // in case something goes wrong -- ensure we don't enter a loop that cannot be exited from
431
- const attemptsMap = {}
420
+ const attemptsMap = {};
421
+ // collections that failed and need a full snapshot on retry
422
+ // mirrors WA Web's ErrorFatal -> force snapshot behavior
423
+ const forceSnapshotCollections = new Set();
432
424
  // keep executing till all collections are done
433
425
  // sometimes a single patch request will not return all the patches (God knows why)
434
426
  // so we fetch till they're all done (this is determined by the "has_more_patches" flag)
435
427
  while (collectionsToHandle.size) {
436
- const states = {}
437
- const nodes = []
438
-
428
+ const states = {};
429
+ const nodes = [];
439
430
  for (const name of collectionsToHandle) {
440
- const result = await authState.keys.get('app-state-sync-version', [name])
441
- let state = result[name]
431
+ const result = await authState.keys.get('app-state-sync-version', [name]);
432
+ let state = result[name];
442
433
  if (state) {
434
+ state = ensureLTHashStateVersion(state);
443
435
  if (typeof initialVersionMap[name] === 'undefined') {
444
- initialVersionMap[name] = state.version
436
+ initialVersionMap[name] = state.version;
445
437
  }
446
438
  }
447
439
  else {
448
- state = Utils_1.newLTHashState()
440
+ state = newLTHashState();
441
+ }
442
+ states[name] = state;
443
+ const shouldForceSnapshot = forceSnapshotCollections.has(name);
444
+ if (shouldForceSnapshot) {
445
+ forceSnapshotCollections.delete(name);
449
446
  }
450
- states[name] = state
451
- logger.info(`resyncing ${name} from v${state.version}`)
447
+ logger.info(`resyncing ${name} from v${state.version}${shouldForceSnapshot ? ' (forcing snapshot)' : ''}`);
452
448
  nodes.push({
453
449
  tag: 'collection',
454
450
  attrs: {
455
451
  name,
456
452
  version: state.version.toString(),
457
- // return snapshot if being synced from scratch
458
- 'return_snapshot': (!state.version).toString()
453
+ // return snapshot if syncing from scratch or forcing after a failed attempt
454
+ return_snapshot: (shouldForceSnapshot || !state.version).toString()
459
455
  }
460
- })
456
+ });
461
457
  }
462
-
463
458
  const result = await query({
464
459
  tag: 'iq',
465
460
  attrs: {
466
- to: WABinary_1.S_WHATSAPP_NET,
461
+ to: S_WHATSAPP_NET,
467
462
  xmlns: 'w:sync:app:state',
468
463
  type: 'set'
469
464
  },
@@ -474,125 +469,159 @@ const makeChatsSocket = (config) => {
474
469
  content: nodes
475
470
  }
476
471
  ]
477
- })
478
-
472
+ });
479
473
  // extract from binary node
480
- const decoded = await Utils_1.extractSyncdPatches(result, config?.options)
481
-
474
+ const decoded = await extractSyncdPatches(result, config?.options);
482
475
  for (const key in decoded) {
483
- const name = key
484
- const { patches, hasMorePatches, snapshot } = decoded[name]
476
+ const name = key;
477
+ const { patches, hasMorePatches, snapshot } = decoded[name];
485
478
  try {
486
479
  if (snapshot) {
487
- const { state: newState, mutationMap } = await Utils_1.decodeSyncdSnapshot(name, snapshot, getAppStateSyncKey, initialVersionMap[name], appStateMacVerification.snapshot)
488
- states[name] = newState
489
- Object.assign(globalMutationMap, mutationMap)
490
- logger.info(`restored state of ${name} from snapshot to v${newState.version} with mutations`)
491
- await authState.keys.set({ 'app-state-sync-version': { [name]: newState } })
480
+ const { state: newState, mutationMap } = await decodeSyncdSnapshot(name, snapshot, getCachedAppStateSyncKey, initialVersionMap[name], appStateMacVerification.snapshot, logger);
481
+ states[name] = newState;
482
+ Object.assign(globalMutationMap, mutationMap);
483
+ logger.info(`restored state of ${name} from snapshot to v${newState.version} with mutations`);
484
+ await authState.keys.set({ 'app-state-sync-version': { [name]: newState } });
492
485
  }
493
-
494
486
  // only process if there are syncd patches
495
487
  if (patches.length) {
496
- const { state: newState, mutationMap } = await Utils_1.decodePatches(name, patches, states[name], getAppStateSyncKey, config.options, initialVersionMap[name], logger, appStateMacVerification.patch)
497
- await authState.keys.set({ 'app-state-sync-version': { [name]: newState } })
498
- logger.info(`synced ${name} to v${newState.version}`)
499
- initialVersionMap[name] = newState.version
500
- Object.assign(globalMutationMap, mutationMap)
488
+ const { state: newState, mutationMap } = await decodePatches(name, patches, states[name], getCachedAppStateSyncKey, config.options, initialVersionMap[name], logger, appStateMacVerification.patch);
489
+ await authState.keys.set({ 'app-state-sync-version': { [name]: newState } });
490
+ logger.info(`synced ${name} to v${newState.version}`);
491
+ initialVersionMap[name] = newState.version;
492
+ Object.assign(globalMutationMap, mutationMap);
501
493
  }
502
-
503
494
  if (hasMorePatches) {
504
- logger.info(`${name} has more patches...`)
505
- }
506
- else { // collection is done with sync
507
- collectionsToHandle.delete(name)
495
+ logger.info(`${name} has more patches...`);
508
496
  }
509
- }
497
+ else {
498
+ // collection is done with sync
499
+ collectionsToHandle.delete(name);
500
+ }
501
+ }
510
502
  catch (error) {
511
- // if retry attempts overshoot
512
- // or key not found
513
- const isIrrecoverableError = attemptsMap[name] >= MAX_SYNC_ATTEMPTS
514
- || error.output?.statusCode === 404
515
- || error.name === 'TypeError'
516
- logger.info({ name, error: error.stack }, `failed to sync state from version${isIrrecoverableError ? '' : ', removing and trying from scratch'}`)
517
- await authState.keys.set({ 'app-state-sync-version': { [name]: null } })
518
- // increment number of retries
519
- attemptsMap[name] = (attemptsMap[name] || 0) + 1
520
-
521
- if (isIrrecoverableError) {
522
- // stop retrying
523
- collectionsToHandle.delete(name)
503
+ attemptsMap[name] = (attemptsMap[name] || 0) + 1;
504
+ const logData = {
505
+ name,
506
+ attempt: attemptsMap[name],
507
+ version: states[name].version,
508
+ statusCode: error.output?.statusCode,
509
+ errorType: error.name,
510
+ error: error.stack
511
+ };
512
+ if (isMissingKeyError(error) && attemptsMap[name] >= MAX_SYNC_ATTEMPTS) {
513
+ // WA Web treats missing keys as "Blocked" — park the collection
514
+ // until the key arrives via APP_STATE_SYNC_KEY_SHARE.
515
+ logger.warn(logData, `${name} blocked on missing key from v${states[name].version}, parking after ${attemptsMap[name]} attempts`);
516
+ blockedCollections.add(name);
517
+ collectionsToHandle.delete(name);
518
+ }
519
+ else if (isMissingKeyError(error)) {
520
+ // Retry with a snapshot which may use a different key.
521
+ logger.info(logData, `${name} blocked on missing key from v${states[name].version}, retrying with snapshot`);
522
+ forceSnapshotCollections.add(name);
523
+ }
524
+ else if (isAppStateSyncIrrecoverable(error, attemptsMap[name])) {
525
+ logger.warn(logData, `failed to sync ${name} from v${states[name].version}, giving up`);
526
+ collectionsToHandle.delete(name);
527
+ }
528
+ else {
529
+ logger.info(logData, `failed to sync ${name} from v${states[name].version}, forcing snapshot retry`);
530
+ // force a full snapshot on retry to recover from
531
+ // corrupted local state (e.g. LTHash MAC mismatch)
532
+ forceSnapshotCollections.add(name);
524
533
  }
525
534
  }
526
535
  }
527
536
  }
528
- }, authState?.creds?.me?.id || 'resync-app-state')
529
-
530
- const { onMutation } = newAppStateChunkHandler(isInitialSync)
531
-
537
+ }, authState?.creds?.me?.id || 'resync-app-state');
538
+ const { onMutation } = newAppStateChunkHandler(isInitialSync);
532
539
  for (const key in globalMutationMap) {
533
- onMutation(globalMutationMap[key])
540
+ onMutation(globalMutationMap[key]);
541
+ }
542
+ });
543
+ /**
544
+ * fetch the profile picture of a user/group
545
+ * type = "preview" for a low res picture
546
+ * type = "image for the high res picture"
547
+ */
548
+ const profilePictureUrl = async (jid, type = 'preview', timeoutMs) => {
549
+ const baseContent = [{ tag: 'picture', attrs: { type, query: 'url' } }];
550
+ // WA Web only includes tctoken for user JIDs (not groups/newsletters)
551
+ // and never for own profile pic (Chat model for self has no tcToken).
552
+ // Including tctoken for own JID causes the server to never respond.
553
+ const normalizedJid = jidNormalizedUser(jid);
554
+ const isUserJid = isPnUser(normalizedJid) || isLidUser(normalizedJid);
555
+ const me = authState.creds.me;
556
+ const isSelf = me && (normalizedJid === jidNormalizedUser(me.id) || (me.lid && normalizedJid === jidNormalizedUser(me.lid)));
557
+ let content = baseContent;
558
+ if (serverProps.profilePicPrivacyToken && isUserJid && !isSelf) {
559
+ content = await buildTcTokenFromJid({
560
+ authState,
561
+ jid: normalizedJid,
562
+ baseContent,
563
+ getLIDForPN
564
+ });
534
565
  }
535
- })
536
-
537
- // source: https://github.com/WhiskeySockets/Baileys/pull/1677
566
+ jid = jidNormalizedUser(jid);
567
+ const result = await query({
568
+ tag: 'iq',
569
+ attrs: {
570
+ target: jid,
571
+ to: S_WHATSAPP_NET,
572
+ type: 'get',
573
+ xmlns: 'w:profile:picture'
574
+ },
575
+ content
576
+ }, timeoutMs);
577
+ const child = getBinaryNodeChild(result, 'picture');
578
+ return child?.attrs?.url;
579
+ };
538
580
  const createCallLink = async (type, event, timeoutMs) => {
539
- type = type?.toLowerCase()
540
-
541
- if (!type || (type !== 'audio' && type !== 'video')) {
542
- throw new Error('Make sure the type is audio or video!')
543
- }
544
-
545
- const result = await query({
546
- tag: 'call',
547
- attrs: {
548
- id: generateMessageTag(),
549
- to: '@call'
550
- },
551
- content: [{
552
- tag: 'link_create',
553
- attrs: {
554
- media: type
555
- },
556
- content: event ? [{
557
- tag: 'event',
558
- attrs: {
559
- start_time: String(event)
560
- }
561
- }] : undefined
562
- }]
563
- }, timeoutMs)
564
-
565
- const child = WABinary_1.getBinaryNodeChild(result, 'link_create')
566
- const token = child?.attrs?.token
567
-
568
- return type === 'audio' ? Defaults_1.CALL_AUDIO_PREFIX + token : Defaults_1.CALL_VIDEO_PREFIX + token
569
- }
570
-
581
+ const result = await query({
582
+ tag: 'call',
583
+ attrs: {
584
+ id: generateMessageTag(),
585
+ to: '@call'
586
+ },
587
+ content: [
588
+ {
589
+ tag: 'link_create',
590
+ attrs: { media: type },
591
+ content: event ? [{ tag: 'event', attrs: { start_time: String(event.startTime) } }] : undefined
592
+ }
593
+ ]
594
+ }, timeoutMs);
595
+ const child = getBinaryNodeChild(result, 'link_create');
596
+ return child?.attrs?.token;
597
+ };
571
598
  const sendPresenceUpdate = async (type, toJid) => {
572
- const me = authState.creds.me
573
-
574
- if (type === 'available' || type === 'unavailable') {
599
+ const me = authState.creds.me;
600
+ const isAvailableType = type === 'available';
601
+ if (isAvailableType || type === 'unavailable') {
575
602
  if (!me.name) {
576
- logger.warn('no name present, ignoring presence update request...')
577
- return
603
+ logger.warn('no name present, ignoring presence update request...');
604
+ return;
605
+ }
606
+ ev.emit('connection.update', { isOnline: isAvailableType });
607
+ if (isAvailableType) {
608
+ void sendUnifiedSession();
578
609
  }
579
-
580
- ev.emit('connection.update', { isOnline: type === 'available' })
581
610
  await sendNode({
582
611
  tag: 'presence',
583
612
  attrs: {
584
613
  name: me.name.replace(/@/g, ''),
585
614
  type
586
615
  }
587
- })
616
+ });
588
617
  }
589
618
  else {
590
- const { server } = WABinary_1.jidDecode(toJid)
591
-
619
+ const { server } = jidDecode(toJid);
620
+ const isLid = server === 'lid';
592
621
  await sendNode({
593
622
  tag: 'chatstate',
594
623
  attrs: {
595
- from: server === 'lid' ? me.lid : me.id,
624
+ from: isLid ? me.lid : me.id,
596
625
  to: toJid
597
626
  },
598
627
  content: [
@@ -601,96 +630,82 @@ const makeChatsSocket = (config) => {
601
630
  attrs: type === 'recording' ? { media: 'audio' } : {}
602
631
  }
603
632
  ]
604
- })
633
+ });
605
634
  }
606
- }
607
-
635
+ };
608
636
  /**
609
637
  * @param toJid the jid to subscribe to
610
638
  * @param tcToken token for subscription, use if present
611
639
  */
612
- const presenceSubscribe = (toJid, tcToken) => (sendNode({
613
- tag: 'presence',
614
- attrs: {
615
- to: toJid,
616
- id: generateMessageTag(),
617
- type: 'subscribe'
618
- },
619
- content: tcToken
620
- ? [
621
- {
622
- tag: 'tctoken',
623
- attrs: {},
624
- content: tcToken
625
- }
626
- ]
627
- : undefined
628
- }))
629
-
640
+ const presenceSubscribe = async (toJid) => {
641
+ // Only include tctoken for user JIDs — groups/newsletters don't use tctokens
642
+ const normalizedToJid = jidNormalizedUser(toJid);
643
+ const isUserJid = isPnUser(normalizedToJid) || isLidUser(normalizedToJid);
644
+ const tcTokenContent = isUserJid
645
+ ? await buildTcTokenFromJid({ authState, jid: normalizedToJid, getLIDForPN })
646
+ : undefined;
647
+ return sendNode({
648
+ tag: 'presence',
649
+ attrs: {
650
+ to: toJid,
651
+ id: generateMessageTag(),
652
+ type: 'subscribe'
653
+ },
654
+ content: tcTokenContent
655
+ });
656
+ };
630
657
  const handlePresenceUpdate = ({ tag, attrs, content }) => {
631
- let presence
632
- const jid = attrs.from
633
- const participant = attrs.participant || attrs.from
634
-
635
- if (shouldIgnoreJid(jid) && jid !== '@s.whatsapp.net') {
636
- return
658
+ let presence;
659
+ const jid = attrs.from;
660
+ const participant = attrs.participant || attrs.from;
661
+ if (shouldIgnoreJid(jid) && jid !== S_WHATSAPP_NET) {
662
+ return;
637
663
  }
638
-
639
664
  if (tag === 'presence') {
640
665
  presence = {
641
666
  lastKnownPresence: attrs.type === 'unavailable' ? 'unavailable' : 'available',
642
- lastSeen: attrs.last && attrs.last !== 'deny' ? +attrs.last : undefined
643
- }
667
+ lastSeen: attrs.last && attrs.last !== 'deny' ? +attrs.last : undefined,
668
+ groupOnlineCount: attrs.count ? +attrs.count : undefined
669
+ };
644
670
  }
645
-
646
671
  else if (Array.isArray(content)) {
647
- const [firstChild] = content
648
- let type = firstChild.tag
649
-
672
+ const [firstChild] = content;
673
+ let type = firstChild.tag;
650
674
  if (type === 'paused') {
651
- type = 'available'
675
+ type = 'available';
652
676
  }
653
-
654
677
  if (firstChild.attrs?.media === 'audio') {
655
- type = 'recording'
678
+ type = 'recording';
656
679
  }
657
-
658
- presence = { lastKnownPresence: type }
680
+ presence = { lastKnownPresence: type };
659
681
  }
660
-
661
682
  else {
662
- logger.error({ tag, attrs, content }, 'recv invalid presence node')
683
+ logger.error({ tag, attrs, content }, 'recv invalid presence node');
663
684
  }
664
-
665
685
  if (presence) {
666
- ev.emit('presence.update', { id: jid, presences: { [participant]: presence } })
686
+ ev.emit('presence.update', { id: jid, presences: { [participant]: presence } });
667
687
  }
668
- }
669
-
688
+ };
670
689
  const appPatch = async (patchCreate) => {
671
- const name = patchCreate.type
672
- const myAppStateKeyId = authState.creds.myAppStateKeyId
673
-
690
+ const name = patchCreate.type;
691
+ const myAppStateKeyId = authState.creds.myAppStateKeyId;
674
692
  if (!myAppStateKeyId) {
675
- throw new boom_1.Boom('App state key not present!', { statusCode: 400 })
693
+ throw new Boom('App state key not present!', { statusCode: 400 });
676
694
  }
677
-
678
- let initial
679
- let encodeResult
680
-
681
- await processingMutex.mutex(async () => {
695
+ let initial;
696
+ let encodeResult;
697
+ await appStatePatchMutex.mutex(async () => {
682
698
  await authState.keys.transaction(async () => {
683
- logger.debug({ patch: patchCreate }, 'applying app patch')
684
- await resyncAppState([name], false)
685
- const { [name]: currentSyncVersion } = await authState.keys.get('app-state-sync-version', [name])
686
- initial = currentSyncVersion || Utils_1.newLTHashState()
687
- encodeResult = await Utils_1.encodeSyncdPatch(patchCreate, myAppStateKeyId, initial, getAppStateSyncKey)
688
- const { patch, state } = encodeResult
689
-
699
+ logger.debug({ patch: patchCreate }, 'applying app patch');
700
+ await resyncAppState([name], false);
701
+ const { [name]: currentSyncVersion } = await authState.keys.get('app-state-sync-version', [name]);
702
+ initial = currentSyncVersion ? ensureLTHashStateVersion(currentSyncVersion) : newLTHashState();
703
+ encodeResult = await encodeSyncdPatch(patchCreate, myAppStateKeyId, initial, getAppStateSyncKey);
704
+ const { patch, state } = encodeResult;
690
705
  const node = {
691
706
  tag: 'iq',
692
707
  attrs: {
693
- to: WABinary_1.S_WHATSAPP_NET,
708
+ to: S_WHATSAPP_NET,
694
709
  type: 'set',
695
710
  xmlns: 'w:sync:app:state'
696
711
  },
@@ -704,88 +719,94 @@ const makeChatsSocket = (config) => {
704
719
  attrs: {
705
720
  name,
706
721
  version: (state.version - 1).toString(),
707
- 'return_snapshot': 'false'
722
+ return_snapshot: 'false'
708
723
  },
709
724
  content: [
710
725
  {
711
726
  tag: 'patch',
712
727
  attrs: {},
713
- content: WAProto_1.proto.SyncdPatch.encode(patch).finish()
728
+ content: proto.SyncdPatch.encode(patch).finish()
714
729
  }
715
730
  ]
716
731
  }
717
732
  ]
718
733
  }
719
734
  ]
720
- }
721
- await query(node)
722
- await authState.keys.set({ 'app-state-sync-version': { [name]: state } })
723
- }, authState?.creds?.me?.id || 'app-patch')
724
- })
725
-
735
+ };
736
+ await query(node);
737
+ await authState.keys.set({ 'app-state-sync-version': { [name]: state } });
738
+ }, authState?.creds?.me?.id || 'app-patch');
739
+ });
726
740
  if (config.emitOwnEvents) {
727
- const { onMutation } = newAppStateChunkHandler(false)
728
- const { mutationMap } = await Utils_1.decodePatches(name, [{ ...encodeResult.patch, version: { version: encodeResult.state.version }, }], initial, getAppStateSyncKey, config.options, undefined, logger)
729
-
741
+ const { onMutation } = newAppStateChunkHandler(false);
742
+ const { mutationMap } = await decodePatches(name, [{ ...encodeResult.patch, version: { version: encodeResult.state.version } }], initial, getAppStateSyncKey, config.options, undefined, logger);
730
743
  for (const key in mutationMap) {
731
- onMutation(mutationMap[key])
744
+ onMutation(mutationMap[key]);
732
745
  }
733
746
  }
734
- }
735
-
736
- /** sending non-abt props may fix QR scan fail if server expects */
747
+ };
748
+ /** fetch AB props */
737
749
  const fetchProps = async () => {
738
750
  const resultNode = await query({
739
751
  tag: 'iq',
740
752
  attrs: {
741
- to: WABinary_1.S_WHATSAPP_NET,
742
- xmlns: 'w',
743
- type: 'get',
753
+ to: S_WHATSAPP_NET,
754
+ xmlns: 'abt',
755
+ type: 'get'
744
756
  },
745
757
  content: [
746
- { tag: 'props', attrs: {
747
- protocol: '2',
748
- hash: authState?.creds?.lastPropHash || ''
749
- } }
758
+ {
759
+ tag: 'props',
760
+ attrs: {
761
+ protocol: '1',
762
+ ...(authState?.creds?.lastPropHash ? { hash: authState.creds.lastPropHash } : {})
763
+ }
764
+ }
750
765
  ]
751
- })
752
-
753
- const propsNode = WABinary_1.getBinaryNodeChild(resultNode, 'props')
754
- let props = {}
755
-
766
+ });
767
+ const propsNode = getBinaryNodeChild(resultNode, 'props');
768
+ let props = {};
756
769
  if (propsNode) {
757
- if (propsNode.attrs?.hash) { // on some clients, the hash is returning as undefined
758
- authState.creds.lastPropHash = propsNode?.attrs?.hash
759
- ev.emit('creds.update', authState.creds)
770
+ if (propsNode.attrs?.hash) {
771
+ // on some clients, the hash is returning as undefined
772
+ authState.creds.lastPropHash = propsNode?.attrs?.hash;
773
+ ev.emit('creds.update', authState.creds);
760
774
  }
761
-
762
- props = WABinary_1.reduceBinaryNodeToDictionary(propsNode, 'prop')
775
+ props = reduceBinaryNodeToDictionary(propsNode, 'prop');
763
776
  }
764
- logger.debug('fetched props')
765
- return props
766
- }
767
-
777
+ // Extract protocol-relevant AB props (only the ones we need)
778
+ const privacyTokenProp = props['10518'] ?? props['privacy_token_sending_on_all_1_on_1_messages'];
779
+ if (privacyTokenProp !== undefined) {
780
+ serverProps.privacyTokenOn1to1 = privacyTokenProp === 'true' || privacyTokenProp === '1';
781
+ }
782
+ const profilePicProp = props['9666'] ?? props['profile_scraping_privacy_token_in_photo_iq'];
783
+ if (profilePicProp !== undefined) {
784
+ serverProps.profilePicPrivacyToken = profilePicProp === 'true' || profilePicProp === '1';
785
+ }
786
+ const lidIssueProp = props['14303'] ?? props['lid_trusted_token_issue_to_lid'];
787
+ if (lidIssueProp !== undefined) {
788
+ serverProps.lidTrustedTokenIssueToLid = lidIssueProp === 'true' || lidIssueProp === '1';
789
+ }
790
+ logger.debug({ serverProps }, 'fetched props');
791
+ return props;
792
+ };
768
793
  /**
769
794
  * modify a chat -- mark unread, read etc.
770
795
  * lastMessages must be sorted in reverse chronologically
771
- * requires the last messages till the last message received required for archive & unread
772
- */
796
+ * requires the last messages till the last message received; required for archive & unread
797
+ */
773
798
  const chatModify = (mod, jid) => {
774
- const patch = Utils_1.chatModificationToAppPatch(mod, jid)
775
- return appPatch(patch)
776
- }
777
-
799
+ const patch = chatModificationToAppPatch(mod, jid);
800
+ return appPatch(patch);
801
+ };
778
802
  /**
779
803
  * Enable/Disable link preview privacy, not related to baileys link preview generation
780
804
  */
781
805
  const updateDisableLinkPreviewsPrivacy = (isPreviewsDisabled) => {
782
- return chatModify({
783
- disableLinkPreviews: {
784
- isPreviewsDisabled
785
- }
786
- }, '')
787
- }
788
-
806
+ return chatModify({
807
+ disableLinkPreviews: { isPreviewsDisabled }
808
+ }, '');
809
+ };
789
810
  /**
790
811
  * Star or Unstar a message
791
812
  */
@@ -795,27 +816,24 @@ const makeChatsSocket = (config) => {
795
816
  messages,
796
817
  star
797
818
  }
798
- }, jid)
799
- }
800
-
819
+ }, jid);
820
+ };
801
821
  /**
802
- * Add Or Edit Contact
822
+ * Add or Edit Contact
803
823
  */
804
824
  const addOrEditContact = (jid, contact) => {
805
- return chatModify({
806
- contact
807
- }, jid)
808
- }
809
-
825
+ return chatModify({
826
+ contact
827
+ }, jid);
828
+ };
810
829
  /**
811
830
  * Remove Contact
812
831
  */
813
- const removeContact = (jid) => {
814
- return chatModify({
815
- contact: null
816
- }, jid)
817
- }
818
-
832
+ const removeContact = (jid) => {
833
+ return chatModify({
834
+ contact: null
835
+ }, jid);
836
+ };
819
837
  /**
820
838
  * Adds label
821
839
  */
@@ -824,9 +842,8 @@ const makeChatsSocket = (config) => {
824
842
  addLabel: {
825
843
  ...labels
826
844
  }
827
- }, jid)
828
- }
829
-
845
+ }, jid);
846
+ };
830
847
  /**
831
848
  * Adds label for the chats
832
849
  */
@@ -835,9 +852,8 @@ const makeChatsSocket = (config) => {
835
852
  addChatLabel: {
836
853
  labelId
837
854
  }
838
- }, jid)
839
- }
840
-
855
+ }, jid);
856
+ };
841
857
  /**
842
858
  * Removes label for the chat
843
859
  */
@@ -846,9 +862,8 @@ const makeChatsSocket = (config) => {
846
862
  removeChatLabel: {
847
863
  labelId
848
864
  }
849
- }, jid)
850
- }
851
-
865
+ }, jid);
866
+ };
852
867
  /**
853
868
  * Adds label for the message
854
869
  */
@@ -858,9 +873,8 @@ const makeChatsSocket = (config) => {
858
873
  messageId,
859
874
  labelId
860
875
  }
861
- }, jid)
862
- }
863
-
876
+ }, jid);
877
+ };
864
878
  /**
865
879
  * Removes label for the message
866
880
  */
@@ -870,114 +884,129 @@ const makeChatsSocket = (config) => {
870
884
  messageId,
871
885
  labelId
872
886
  }
873
- }, jid)
874
- }
875
-
887
+ }, jid);
888
+ };
876
889
  /**
877
- * Removes Chats
878
- */
879
- const clearMessage = (jid, key, timeStamp) => {
880
- return chatModify({
881
- delete: true,
882
- lastMessages: [{
883
- key: key,
884
- messageTimestamp: timeStamp
885
- }],
886
- }, jid)
887
- }
888
-
889
- /**
890
890
  * Add or Edit Quick Reply
891
891
  */
892
892
  const addOrEditQuickReply = (quickReply) => {
893
893
  return chatModify({
894
894
  quickReply
895
- }, '')
896
- }
897
-
895
+ }, '');
896
+ };
898
897
  /**
899
898
  * Remove Quick Reply
900
899
  */
901
900
  const removeQuickReply = (timestamp) => {
902
901
  return chatModify({
903
902
  quickReply: { timestamp, deleted: true }
904
- }, '')
905
- }
906
-
903
+ }, '');
904
+ };
907
905
  /**
908
906
  * queries need to be fired on connection open
909
907
  * help ensure parity with WA Web
910
908
  * */
911
909
  const executeInitQueries = async () => {
912
- await Promise.all([
913
- fetchProps(),
914
- fetchBlocklist(),
915
- fetchPrivacySettings(),
916
- ])
917
- }
918
-
910
+ await Promise.all([fetchProps(), fetchBlocklist(), fetchPrivacySettings()]);
911
+ };
919
912
  const upsertMessage = ev.createBufferedFunction(async (msg, type) => {
920
- ev.emit('messages.upsert', { messages: [msg], type })
913
+ ev.emit('messages.upsert', { messages: [msg], type });
921
914
  if (!!msg.pushName) {
922
- let jid = msg.key.fromMe ? authState.creds.me.id : (msg.key.participant || msg.key.remoteJid)
923
- jid = WABinary_1.jidNormalizedUser(jid)
924
-
915
+ let jid = msg.key.fromMe ? authState.creds.me.id : msg.key.participant || msg.key.remoteJid;
916
+ jid = jidNormalizedUser(jid);
925
917
  if (!msg.key.fromMe) {
926
- ev.emit('contacts.update', [{ id: jid, notify: msg.pushName, verifiedName: msg.verifiedBizName }])
918
+ ev.emit('contacts.update', [{ id: jid, notify: msg.pushName, verifiedName: msg.verifiedBizName }]);
927
919
  }
928
-
929
920
  // update our pushname too
930
921
  if (msg.key.fromMe && msg.pushName && authState.creds.me?.name !== msg.pushName) {
931
- ev.emit('creds.update', { me: { ...authState.creds.me, name: msg.pushName } })
922
+ ev.emit('creds.update', { me: { ...authState.creds.me, name: msg.pushName } });
932
923
  }
933
924
  }
934
-
935
- const historyMsg = Utils_1.getHistoryMsg(msg.message)
925
+ const historyMsg = getHistoryMsg(msg.message);
936
926
  const shouldProcessHistoryMsg = historyMsg
937
- ? (shouldSyncHistoryMessage(historyMsg)
938
- && Defaults_1.PROCESSABLE_HISTORY_TYPES.includes(historyMsg.syncType))
939
- : false
940
-
941
- if (historyMsg && syncState === Types_1.SyncState.AwaitingInitialSync) {
927
+ ? shouldSyncHistoryMessage(historyMsg) &&
928
+ PROCESSABLE_HISTORY_TYPES.includes(historyMsg.syncType)
929
+ : false;
930
+ if (historyMsg && shouldProcessHistoryMsg) {
931
+ const syncType = historyMsg.syncType;
932
+ // INITIAL_BOOTSTRAP — fire immediately, no progress check (same as WA Web K function)
933
+ if (syncType === proto.HistorySync.HistorySyncType.INITIAL_BOOTSTRAP &&
934
+ !historySyncStatus.initialBootstrapComplete) {
935
+ historySyncStatus.initialBootstrapComplete = true;
936
+ ev.emit('messaging-history.status', {
937
+ syncType,
938
+ status: 'complete',
939
+ explicit: true
940
+ });
941
+ }
942
+ // RECENT with progress === 100 — explicit completion
943
+ if (syncType === proto.HistorySync.HistorySyncType.RECENT &&
944
+ historyMsg.progress === 100 &&
945
+ !historySyncStatus.recentSyncComplete) {
946
+ historySyncStatus.recentSyncComplete = true;
947
+ clearTimeout(historySyncPausedTimeout);
948
+ historySyncPausedTimeout = undefined;
949
+ ev.emit('messaging-history.status', {
950
+ syncType,
951
+ status: 'complete',
952
+ explicit: true
953
+ });
954
+ }
955
+ // Reset 120s paused timeout on any RECENT chunk (like WA Web's handleChunkProgress)
956
+ if (syncType === proto.HistorySync.HistorySyncType.RECENT && !historySyncStatus.recentSyncComplete) {
957
+ clearTimeout(historySyncPausedTimeout);
958
+ historySyncPausedTimeout = setTimeout(() => {
959
+ if (!historySyncStatus.recentSyncComplete) {
960
+ historySyncStatus.recentSyncComplete = true;
961
+ ev.emit('messaging-history.status', {
962
+ syncType: proto.HistorySync.HistorySyncType.RECENT,
963
+ status: 'paused',
964
+ explicit: false
965
+ });
966
+ }
967
+ historySyncPausedTimeout = undefined;
968
+ }, HISTORY_SYNC_PAUSED_TIMEOUT_MS);
969
+ }
970
+ }
971
+ // State machine: decide on sync and flush
972
+ if (historyMsg && syncState === SyncState.AwaitingInitialSync) {
942
973
  if (awaitingSyncTimeout) {
943
- clearTimeout(awaitingSyncTimeout)
944
- awaitingSyncTimeout = undefined
974
+ clearTimeout(awaitingSyncTimeout);
975
+ awaitingSyncTimeout = undefined;
945
976
  }
946
-
947
977
  if (shouldProcessHistoryMsg) {
948
- syncState = Types_1.SyncState.Syncing
949
- logger.info('Transitioned to Syncing state')
950
- // Let doAppStateSync handle the final flush after it`s done
951
- } else {
952
- syncState = Types_1.SyncState.Online
953
- logger.info('History sync skipped, transitioning to Online state and flushing buffer')
954
- ev.flush()
978
+ syncState = SyncState.Syncing;
979
+ logger.info('Transitioned to Syncing state');
980
+ // Let doAppStateSync handle the final flush after it's done
981
+ }
982
+ else {
983
+ syncState = SyncState.Online;
984
+ logger.info('History sync skipped, transitioning to Online state and flushing buffer');
985
+ ev.flush();
955
986
  }
956
987
  }
957
-
958
988
  const doAppStateSync = async () => {
959
- if (syncState === Types_1.SyncState.Syncing) {
960
- logger.info('Doing app state sync')
961
- await resyncAppState(Types_1.ALL_WA_PATCH_NAMES, true)
962
-
963
- // Sync is complete, go online and flush everything
964
- syncState = Types_1.SyncState.Online
965
- logger.info('App state sync complete, transitioning to Online state and flushing buffer')
966
- ev.flush()
967
-
968
- const accountSyncCounter = (authState.creds.accountSyncCounter || 0) + 1
969
- ev.emit('creds.update', { accountSyncCounter })
970
- }
971
- }
972
-
989
+ if (syncState === SyncState.Syncing) {
990
+ // All collections will be synced, so clear any blocked ones
991
+ blockedCollections.clear();
992
+ logger.info('Doing app state sync');
993
+ await resyncAppState(ALL_WA_PATCH_NAMES, true);
994
+ // Sync is complete, go online and flush everything
995
+ syncState = SyncState.Online;
996
+ logger.info('App state sync complete, transitioning to Online state and flushing buffer');
997
+ ev.flush();
998
+ const accountSyncCounter = (authState.creds.accountSyncCounter || 0) + 1;
999
+ ev.emit('creds.update', { accountSyncCounter });
1000
+ }
1001
+ };
973
1002
  await Promise.all([
974
1003
  (async () => {
975
1004
  if (shouldProcessHistoryMsg) {
976
- await doAppStateSync()
1005
+ await doAppStateSync();
977
1006
  }
978
1007
  })(),
979
- Utils_1.processMessage(msg, {
980
- signalRepository,
1008
+ processMessage(msg, {
1009
+ signalRepository,
981
1010
  shouldProcessHistoryMsg,
982
1011
  placeholderResendCache,
983
1012
  ev,
@@ -985,101 +1014,147 @@ const makeChatsSocket = (config) => {
985
1014
  keyStore: authState.keys,
986
1015
  logger,
987
1016
  options: config.options,
988
- getMessage: config.getMessage,
1017
+ getMessage
989
1018
  })
990
- ])
991
-
992
- if (msg.message?.protocolMessage?.appStateSyncKeyShare && syncState === Types_1.SyncState.Syncing) {
993
- logger.info('App state sync key arrived, triggering app state sync')
994
- await doAppStateSync()
1019
+ ]);
1020
+ // If the app state key arrives and we are waiting to sync, trigger the sync now.
1021
+ if (msg.message?.protocolMessage?.appStateSyncKeyShare && syncState === SyncState.Syncing) {
1022
+ logger.info('App state sync key arrived, triggering app state sync');
1023
+ await doAppStateSync();
995
1024
  }
996
- })
997
-
998
- ws.on('CB:presence', handlePresenceUpdate)
999
- ws.on('CB:chatstate', handlePresenceUpdate)
1025
+ });
1026
+ ws.on('CB:presence', handlePresenceUpdate);
1027
+ ws.on('CB:chatstate', handlePresenceUpdate);
1000
1028
  ws.on('CB:ib,,dirty', async (node) => {
1001
- const { attrs } = WABinary_1.getBinaryNodeChild(node, 'dirty')
1002
- const type = attrs.type
1003
-
1029
+ const { attrs } = getBinaryNodeChild(node, 'dirty');
1030
+ const type = attrs.type;
1004
1031
  switch (type) {
1005
1032
  case 'account_sync':
1006
1033
  if (attrs.timestamp) {
1007
- let { lastAccountSyncTimestamp } = authState.creds
1034
+ let { lastAccountSyncTimestamp } = authState.creds;
1008
1035
  if (lastAccountSyncTimestamp) {
1009
- await cleanDirtyBits('account_sync', lastAccountSyncTimestamp)
1036
+ await cleanDirtyBits('account_sync', lastAccountSyncTimestamp);
1010
1037
  }
1011
- lastAccountSyncTimestamp = +attrs.timestamp
1012
- ev.emit('creds.update', { lastAccountSyncTimestamp })
1038
+ lastAccountSyncTimestamp = +attrs.timestamp;
1039
+ ev.emit('creds.update', { lastAccountSyncTimestamp });
1013
1040
  }
1014
- break
1041
+ break;
1015
1042
  case 'groups':
1016
- await groupFetchAllParticipating()
1017
- await cleanDirtyBits('groups')
1018
- break
1043
+ // handled in groups.ts
1044
+ break;
1019
1045
  default:
1020
- logger.info({ node }, 'received unknown sync')
1021
- break
1046
+ logger.info({ node }, 'received unknown sync');
1047
+ break;
1022
1048
  }
1023
- })
1024
-
1049
+ });
1025
1050
  ev.on('connection.update', ({ connection, receivedPendingNotifications }) => {
1051
+ if (connection === 'close') {
1052
+ blockedCollections.clear();
1053
+ clearTimeout(historySyncPausedTimeout);
1054
+ historySyncPausedTimeout = undefined;
1055
+ }
1026
1056
  if (connection === 'open') {
1027
1057
  if (fireInitQueries) {
1028
- executeInitQueries()
1029
- .catch(error => onUnexpectedError(error, 'init queries'))
1058
+ executeInitQueries().catch(error => onUnexpectedError(error, 'init queries'));
1030
1059
  }
1031
- sendPresenceUpdate(markOnlineOnConnect ? 'available' : 'unavailable')
1032
- .catch(error => onUnexpectedError(error, 'presence update requests'))
1060
+ sendPresenceUpdate(markOnlineOnConnect ? 'available' : 'unavailable').catch(error => onUnexpectedError(error, 'presence update requests'));
1033
1061
  }
1034
-
1035
- if (!receivedPendingNotifications || syncState !== Types_1.SyncState.Connecting) {
1036
- return
1062
+ if (!receivedPendingNotifications || syncState !== SyncState.Connecting) {
1063
+ return;
1037
1064
  }
1038
-
1039
- syncState = Types_1.AwaitingInitialSync
1040
- logger.info('Connection is now AwaitingInitialSync, buffering events')
1041
- ev.buffer()
1042
-
1043
- const willSyncHistory = shouldSyncHistoryMessage(WAProto_1.proto.Message.HistorySyncNotification.fromObject({
1044
- syncType: WAProto_1.proto.HistorySync.HistorySyncType.RECENT
1045
- }))
1046
-
1065
+ historySyncStatus.initialBootstrapComplete = false;
1066
+ historySyncStatus.recentSyncComplete = false;
1067
+ clearTimeout(historySyncPausedTimeout);
1068
+ historySyncPausedTimeout = undefined;
1069
+ syncState = SyncState.AwaitingInitialSync;
1070
+ logger.info('Connection is now AwaitingInitialSync, buffering events');
1071
+ ev.buffer();
1072
+ const willSyncHistory = shouldSyncHistoryMessage(proto.Message.HistorySyncNotification.create({
1073
+ syncType: proto.HistorySync.HistorySyncType.RECENT
1074
+ }));
1047
1075
  if (!willSyncHistory) {
1048
- logger.info('History sync is disabled by config, not waiting for notification. Transitioning to Online.')
1049
- syncState = Types_1.SyncState.Online
1050
- setTimeout(() => ev.flush(), 0)
1051
- return
1076
+ logger.info('History sync is disabled by config, not waiting for notification. Transitioning to Online.');
1077
+ syncState = SyncState.Online;
1078
+ setTimeout(() => ev.flush(), 0);
1079
+ return;
1052
1080
  }
1053
-
1054
- logger.info('History sync is enabled, awaiting notification with a 20s timeout.')
1055
-
1081
+ // On reconnection (accountSyncCounter > 0), the server does not push
1082
+ // history sync notifications the device already has its data.
1083
+ // Skip the 20s wait and go online immediately.
1084
+ if (authState.creds.accountSyncCounter > 0) {
1085
+ logger.info('Reconnection with existing sync data, skipping history sync wait. Transitioning to Online.');
1086
+ syncState = SyncState.Online;
1087
+ setTimeout(() => ev.flush(), 0);
1088
+ return;
1089
+ }
1090
+ logger.info('First connection, awaiting history sync notification with a 20s timeout.');
1056
1091
  if (awaitingSyncTimeout) {
1057
- clearTimeout(awaitingSyncTimeout)
1092
+ clearTimeout(awaitingSyncTimeout);
1058
1093
  }
1059
-
1060
1094
  awaitingSyncTimeout = setTimeout(() => {
1061
- if (syncState === Types_1.SyncState.AwaitingInitialSync) {
1062
- logger.warn('Timeout in AwaitingInitialSync, forcing state to Online and flushing buffer')
1063
- syncState = Types_1.SyncState.Online
1064
- ev.flush()
1065
- }
1066
- }, 20_000)
1067
- })
1068
-
1095
+ if (syncState === SyncState.AwaitingInitialSync) {
1096
+ logger.warn('Timeout in AwaitingInitialSync, forcing state to Online and flushing buffer');
1097
+ syncState = SyncState.Online;
1098
+ ev.flush();
1099
+ // Increment so subsequent reconnections skip the 20s wait.
1100
+ // Late-arriving history is still processed via processMessage
1101
+ // regardless of the state machine phase.
1102
+ const accountSyncCounter = (authState.creds.accountSyncCounter || 0) + 1;
1103
+ ev.emit('creds.update', { accountSyncCounter });
1104
+ }
1105
+ }, 20000);
1106
+ });
1107
+ // When an app state sync key arrives (myAppStateKeyId is set) and there are
1108
+ // collections blocked on a missing key, trigger a re-sync for just those collections.
1109
+ // This mirrors WA Web's Blocked → retry-on-key-arrival behavior.
1110
+ ev.on('creds.update', ({ myAppStateKeyId }) => {
1111
+ if (!myAppStateKeyId || blockedCollections.size === 0) {
1112
+ return;
1113
+ }
1114
+ // If we're in the middle of a full sync, doAppStateSync handles all collections
1115
+ if (syncState === SyncState.Syncing) {
1116
+ blockedCollections.clear();
1117
+ return;
1118
+ }
1119
+ const collections = [...blockedCollections];
1120
+ blockedCollections.clear();
1121
+ logger.info({ collections }, 'app state sync key arrived, re-syncing blocked collections');
1122
+ resyncAppState(collections, false).catch(error => onUnexpectedError(error, 'blocked collections resync'));
1123
+ });
1124
+ ev.on('lid-mapping.update', async ({ lid, pn }) => {
1125
+ try {
1126
+ await signalRepository.lidMapping.storeLIDPNMappings([{ lid, pn }]);
1127
+ }
1128
+ catch (error) {
1129
+ logger.warn({ lid, pn, error }, 'Failed to store LID-PN mapping');
1130
+ }
1131
+ });
1132
+ registerSocketEndHandler(() => {
1133
+ if (awaitingSyncTimeout) {
1134
+ clearTimeout(awaitingSyncTimeout);
1135
+ awaitingSyncTimeout = undefined;
1136
+ }
1137
+ if (!config.placeholderResendCache && placeholderResendCache.close) {
1138
+ placeholderResendCache.close();
1139
+ }
1140
+ syncState = SyncState.Connecting;
1141
+ privacySettings = undefined;
1142
+ });
1069
1143
  return {
1070
- ...sock,
1071
- star,
1072
- addOrEditContact,
1073
- removeContact,
1074
- processingMutex,
1144
+ ...sock,
1145
+ serverProps,
1146
+ createCallLink,
1147
+ getBotListV2,
1148
+ messageMutex,
1149
+ receiptMutex,
1150
+ appStatePatchMutex,
1151
+ notificationMutex,
1075
1152
  fetchPrivacySettings,
1076
1153
  upsertMessage,
1077
1154
  appPatch,
1078
- createCallLink,
1079
1155
  sendPresenceUpdate,
1080
- presenceSubscribe,
1081
- getBotListV2,
1082
- getLidUser,
1156
+ presenceSubscribe,
1157
+ profilePictureUrl,
1083
1158
  fetchBlocklist,
1084
1159
  fetchStatus,
1085
1160
  fetchDisappearingDuration,
@@ -1088,8 +1163,9 @@ const makeChatsSocket = (config) => {
1088
1163
  updateProfileStatus,
1089
1164
  updateProfileName,
1090
1165
  updateBlockStatus,
1166
+ updateDisableLinkPreviewsPrivacy,
1091
1167
  updateCallPrivacy,
1092
- updateMessagesPrivacy,
1168
+ updateMessagesPrivacy,
1093
1169
  updateLastSeenPrivacy,
1094
1170
  updateOnlinePrivacy,
1095
1171
  updateProfilePicturePrivacy,
@@ -1097,22 +1173,21 @@ const makeChatsSocket = (config) => {
1097
1173
  updateReadReceiptsPrivacy,
1098
1174
  updateGroupsAddPrivacy,
1099
1175
  updateDefaultDisappearingMode,
1100
- updateDisableLinkPreviewsPrivacy,
1101
1176
  getBusinessProfile,
1102
1177
  resyncAppState,
1103
1178
  chatModify,
1104
1179
  cleanDirtyBits,
1180
+ addOrEditContact,
1181
+ removeContact,
1182
+ placeholderResendCache,
1105
1183
  addLabel,
1106
1184
  addChatLabel,
1107
1185
  removeChatLabel,
1108
1186
  addMessageLabel,
1109
1187
  removeMessageLabel,
1110
- clearMessage,
1188
+ star,
1111
1189
  addOrEditQuickReply,
1112
1190
  removeQuickReply
1113
- }
1114
- }
1115
-
1116
- module.exports = {
1117
- makeChatsSocket
1118
- }
1191
+ };
1192
+ };
1193
+ //# sourceMappingURL=chats.js.map