@fer2809fl/baileys 1.4.9 → 7.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 (481) hide show
  1. package/LICENSE +21 -674
  2. package/README.md +556 -523
  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 +4347 -45387
  7. package/WAProto/index.js +65475 -137445
  8. package/engine-requirements.js +10 -0
  9. package/lib/Defaults/index.d.ts +34 -18
  10. package/lib/Defaults/index.d.ts.map +1 -0
  11. package/lib/Defaults/index.js +95 -67
  12. package/lib/Defaults/index.js.map +1 -0
  13. package/lib/Signal/Group/ciphertext-message.d.ts +1 -0
  14. package/lib/Signal/Group/ciphertext-message.d.ts.map +1 -0
  15. package/lib/Signal/Group/ciphertext-message.js +2 -5
  16. package/lib/Signal/Group/ciphertext-message.js.map +1 -0
  17. package/lib/Signal/Group/group-session-builder.d.ts +4 -3
  18. package/lib/Signal/Group/group-session-builder.d.ts.map +1 -0
  19. package/lib/Signal/Group/group-session-builder.js +7 -41
  20. package/lib/Signal/Group/group-session-builder.js.map +1 -0
  21. package/lib/Signal/Group/group_cipher.d.ts +4 -4
  22. package/lib/Signal/Group/group_cipher.d.ts.map +1 -0
  23. package/lib/Signal/Group/group_cipher.js +37 -60
  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 -57
  28. package/lib/Signal/Group/index.js.map +1 -0
  29. package/lib/Signal/Group/keyhelper.d.ts +2 -1
  30. package/lib/Signal/Group/keyhelper.d.ts.map +1 -0
  31. package/lib/Signal/Group/keyhelper.js +7 -44
  32. package/lib/Signal/Group/keyhelper.js.map +1 -0
  33. package/lib/Signal/Group/sender-chain-key.d.ts +3 -2
  34. package/lib/Signal/Group/sender-chain-key.d.ts.map +1 -0
  35. package/lib/Signal/Group/sender-chain-key.js +7 -15
  36. package/lib/Signal/Group/sender-chain-key.js.map +1 -0
  37. package/lib/Signal/Group/sender-key-distribution-message.d.ts +2 -1
  38. package/lib/Signal/Group/sender-key-distribution-message.d.ts.map +1 -0
  39. package/lib/Signal/Group/sender-key-distribution-message.js +8 -11
  40. package/lib/Signal/Group/sender-key-distribution-message.js.map +1 -0
  41. package/lib/Signal/Group/sender-key-message.d.ts +2 -1
  42. package/lib/Signal/Group/sender-key-message.d.ts.map +1 -0
  43. package/lib/Signal/Group/sender-key-message.js +9 -12
  44. package/lib/Signal/Group/sender-key-message.js.map +1 -0
  45. package/lib/Signal/Group/sender-key-name.d.ts +1 -0
  46. package/lib/Signal/Group/sender-key-name.d.ts.map +1 -0
  47. package/lib/Signal/Group/sender-key-name.js +2 -5
  48. package/lib/Signal/Group/sender-key-name.js.map +1 -0
  49. package/lib/Signal/Group/sender-key-record.d.ts +3 -2
  50. package/lib/Signal/Group/sender-key-record.d.ts.map +1 -0
  51. package/lib/Signal/Group/sender-key-record.js +12 -37
  52. package/lib/Signal/Group/sender-key-record.js.map +1 -0
  53. package/lib/Signal/Group/sender-key-state.d.ts +7 -6
  54. package/lib/Signal/Group/sender-key-state.d.ts.map +1 -0
  55. package/lib/Signal/Group/sender-key-state.js +27 -42
  56. package/lib/Signal/Group/sender-key-state.js.map +1 -0
  57. package/lib/Signal/Group/sender-message-key.d.ts +1 -0
  58. package/lib/Signal/Group/sender-message-key.d.ts.map +1 -0
  59. package/lib/Signal/Group/sender-message-key.js +4 -7
  60. package/lib/Signal/Group/sender-message-key.js.map +1 -0
  61. package/lib/Signal/libsignal.d.ts +5 -3
  62. package/lib/Signal/libsignal.d.ts.map +1 -0
  63. package/lib/Signal/libsignal.js +347 -90
  64. package/lib/Signal/libsignal.js.map +1 -0
  65. package/lib/Signal/lid-mapping.d.ts +23 -0
  66. package/lib/Signal/lid-mapping.d.ts.map +1 -0
  67. package/lib/Signal/lid-mapping.js +277 -0
  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 -18
  72. package/lib/Socket/Client/index.js.map +1 -0
  73. package/lib/Socket/Client/types.d.ts +4 -4
  74. package/lib/Socket/Client/types.d.ts.map +1 -0
  75. package/lib/Socket/Client/types.js +4 -6
  76. package/lib/Socket/Client/types.js.map +1 -0
  77. package/lib/Socket/Client/websocket.d.ts +3 -3
  78. package/lib/Socket/Client/websocket.d.ts.map +1 -0
  79. package/lib/Socket/Client/websocket.js +21 -78
  80. package/lib/Socket/Client/websocket.js.map +1 -0
  81. package/lib/Socket/business.d.ts +205 -93
  82. package/lib/Socket/business.d.ts.map +1 -0
  83. package/lib/Socket/business.js +162 -43
  84. package/lib/Socket/business.js.map +1 -0
  85. package/lib/Socket/chats.d.ts +77 -28
  86. package/lib/Socket/chats.d.ts.map +1 -0
  87. package/lib/Socket/chats.js +639 -248
  88. package/lib/Socket/chats.js.map +1 -0
  89. package/lib/Socket/communities.d.ts +340 -0
  90. package/lib/Socket/communities.d.ts.map +1 -0
  91. package/lib/Socket/communities.js +434 -0
  92. package/lib/Socket/communities.js.map +1 -0
  93. package/lib/Socket/groups.d.ts +93 -46
  94. package/lib/Socket/groups.d.ts.map +1 -0
  95. package/lib/Socket/groups.js +260 -102
  96. package/lib/Socket/groups.js.map +1 -0
  97. package/lib/Socket/index.d.ts +253 -98
  98. package/lib/Socket/index.d.ts.map +1 -0
  99. package/lib/Socket/index.js +11 -9
  100. package/lib/Socket/index.js.map +1 -0
  101. package/lib/Socket/messages-recv.d.ts +192 -83
  102. package/lib/Socket/messages-recv.d.ts.map +1 -0
  103. package/lib/Socket/messages-recv.js +1314 -559
  104. package/lib/Socket/messages-recv.js.map +1 -0
  105. package/lib/Socket/messages-send.d.ts +190 -75
  106. package/lib/Socket/messages-send.d.ts.map +1 -0
  107. package/lib/Socket/messages-send.js +937 -581
  108. package/lib/Socket/messages-send.js.map +1 -0
  109. package/lib/Socket/mex.d.ts +4 -0
  110. package/lib/Socket/mex.d.ts.map +1 -0
  111. package/lib/Socket/mex.js +62 -0
  112. package/lib/Socket/mex.js.map +1 -0
  113. package/lib/Socket/newsletter.d.ts +129 -73
  114. package/lib/Socket/newsletter.d.ts.map +1 -0
  115. package/lib/Socket/newsletter.js +373 -222
  116. package/lib/Socket/newsletter.js.map +1 -0
  117. package/lib/Socket/smgss.d.ts +119 -0
  118. package/lib/Socket/smgss.d.ts.map +1 -0
  119. package/lib/Socket/smgss.js +453 -0
  120. package/lib/Socket/smgss.js.map +1 -0
  121. package/lib/Socket/socket.d.ts +59 -270
  122. package/lib/Socket/socket.d.ts.map +1 -0
  123. package/lib/Socket/socket.js +738 -326
  124. package/lib/Socket/socket.js.map +1 -0
  125. package/lib/Store/index.d.ts +4 -2
  126. package/lib/Store/index.d.ts.map +1 -0
  127. package/lib/Store/index.js +4 -8
  128. package/lib/Store/index.js.map +1 -0
  129. package/lib/Store/make-in-memory-store.d.ts +74 -60
  130. package/lib/Store/make-in-memory-store.d.ts.map +1 -0
  131. package/lib/Store/make-in-memory-store.js +130 -119
  132. package/lib/Store/make-in-memory-store.js.map +1 -0
  133. package/lib/Store/make-ordered-dictionary.d.ts +4 -3
  134. package/lib/Store/make-ordered-dictionary.d.ts.map +1 -0
  135. package/lib/Store/make-ordered-dictionary.js +5 -6
  136. package/lib/Store/make-ordered-dictionary.js.map +1 -0
  137. package/lib/Store/object-repository.d.ts +6 -3
  138. package/lib/Store/object-repository.d.ts.map +1 -0
  139. package/lib/Store/object-repository.js +2 -5
  140. package/lib/Store/object-repository.js.map +1 -0
  141. package/lib/Types/Auth.d.ts +19 -5
  142. package/lib/Types/Auth.d.ts.map +1 -0
  143. package/lib/Types/Auth.js +2 -2
  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 -0
  148. package/lib/Types/Bussines.js.map +1 -0
  149. package/lib/Types/Call.d.ts +3 -1
  150. package/lib/Types/Call.d.ts.map +1 -0
  151. package/lib/Types/Call.js +2 -2
  152. package/lib/Types/Call.js.map +1 -0
  153. package/lib/Types/Chat.d.ts +24 -9
  154. package/lib/Types/Chat.d.ts.map +1 -0
  155. package/lib/Types/Chat.js +8 -4
  156. package/lib/Types/Chat.js.map +1 -0
  157. package/lib/Types/Contact.d.ts +7 -4
  158. package/lib/Types/Contact.d.ts.map +1 -0
  159. package/lib/Types/Contact.js +2 -2
  160. package/lib/Types/Contact.js.map +1 -0
  161. package/lib/Types/Events.d.ts +90 -33
  162. package/lib/Types/Events.d.ts.map +1 -0
  163. package/lib/Types/Events.js +2 -2
  164. package/lib/Types/Events.js.map +1 -0
  165. package/lib/Types/GroupMetadata.d.ts +16 -9
  166. package/lib/Types/GroupMetadata.d.ts.map +1 -0
  167. package/lib/Types/GroupMetadata.js +2 -2
  168. package/lib/Types/GroupMetadata.js.map +1 -0
  169. package/lib/Types/Label.d.ts +12 -0
  170. package/lib/Types/Label.d.ts.map +1 -0
  171. package/lib/Types/Label.js +3 -5
  172. package/lib/Types/Label.js.map +1 -0
  173. package/lib/Types/LabelAssociation.d.ts +1 -0
  174. package/lib/Types/LabelAssociation.d.ts.map +1 -0
  175. package/lib/Types/LabelAssociation.js +3 -5
  176. package/lib/Types/LabelAssociation.js.map +1 -0
  177. package/lib/Types/Message.d.ts +176 -148
  178. package/lib/Types/Message.d.ts.map +1 -0
  179. package/lib/Types/Message.js +15 -7
  180. package/lib/Types/Message.js.map +1 -0
  181. package/lib/Types/Mex.d.ts +154 -0
  182. package/lib/Types/Mex.d.ts.map +1 -0
  183. package/lib/Types/Mex.js +39 -0
  184. package/lib/Types/Mex.js.map +1 -0
  185. package/lib/Types/Product.d.ts +2 -1
  186. package/lib/Types/Product.d.ts.map +1 -0
  187. package/lib/Types/Product.js +2 -2
  188. package/lib/Types/Product.js.map +1 -0
  189. package/lib/Types/Signal.d.ts +32 -2
  190. package/lib/Types/Signal.d.ts.map +1 -0
  191. package/lib/Types/Signal.js +2 -2
  192. package/lib/Types/Signal.js.map +1 -0
  193. package/lib/Types/Socket.d.ts +46 -20
  194. package/lib/Types/Socket.d.ts.map +1 -0
  195. package/lib/Types/Socket.js +3 -2
  196. package/lib/Types/Socket.js.map +1 -0
  197. package/lib/Types/State.d.ts +79 -2
  198. package/lib/Types/State.d.ts.map +1 -0
  199. package/lib/Types/State.js +56 -2
  200. package/lib/Types/State.js.map +1 -0
  201. package/lib/Types/USync.d.ts +3 -2
  202. package/lib/Types/USync.d.ts.map +1 -0
  203. package/lib/Types/USync.js +2 -2
  204. package/lib/Types/USync.js.map +1 -0
  205. package/lib/Types/index.d.ts +16 -14
  206. package/lib/Types/index.d.ts.map +1 -0
  207. package/lib/Types/index.js +15 -31
  208. package/lib/Types/index.js.map +1 -0
  209. package/lib/Utils/auth-utils.d.ts +10 -4
  210. package/lib/Utils/auth-utils.d.ts.map +1 -0
  211. package/lib/Utils/auth-utils.js +242 -151
  212. package/lib/Utils/auth-utils.js.map +1 -0
  213. package/lib/Utils/browser-utils.d.ts +4 -0
  214. package/lib/Utils/browser-utils.d.ts.map +1 -0
  215. package/lib/Utils/browser-utils.js +29 -0
  216. package/lib/Utils/browser-utils.js.map +1 -0
  217. package/lib/Utils/business.d.ts +3 -2
  218. package/lib/Utils/business.d.ts.map +1 -0
  219. package/lib/Utils/business.js +66 -69
  220. package/lib/Utils/business.js.map +1 -0
  221. package/lib/Utils/button-handler.d.ts +28 -0
  222. package/lib/Utils/button-handler.d.ts.map +1 -0
  223. package/lib/Utils/button-handler.js +79 -90
  224. package/lib/Utils/button-handler.js.map +1 -0
  225. package/lib/Utils/chat-utils.d.ts +42 -12
  226. package/lib/Utils/chat-utils.d.ts.map +1 -0
  227. package/lib/Utils/chat-utils.js +380 -238
  228. package/lib/Utils/chat-utils.js.map +1 -0
  229. package/lib/Utils/companion-reg-client-utils.d.ts +17 -0
  230. package/lib/Utils/companion-reg-client-utils.d.ts.map +1 -0
  231. package/lib/Utils/companion-reg-client-utils.js +35 -0
  232. package/lib/Utils/companion-reg-client-utils.js.map +1 -0
  233. package/lib/Utils/crypto.d.ts +11 -14
  234. package/lib/Utils/crypto.d.ts.map +1 -0
  235. package/lib/Utils/crypto.js +41 -116
  236. package/lib/Utils/crypto.js.map +1 -0
  237. package/lib/Utils/decode-wa-message.d.ts +36 -5
  238. package/lib/Utils/decode-wa-message.d.ts.map +1 -0
  239. package/lib/Utils/decode-wa-message.js +173 -63
  240. package/lib/Utils/decode-wa-message.js.map +1 -0
  241. package/lib/Utils/event-buffer.d.ts +8 -7
  242. package/lib/Utils/event-buffer.d.ts.map +1 -0
  243. package/lib/Utils/event-buffer.js +174 -70
  244. package/lib/Utils/event-buffer.js.map +1 -0
  245. package/lib/Utils/generics.d.ts +20 -17
  246. package/lib/Utils/generics.d.ts.map +1 -0
  247. package/lib/Utils/generics.js +159 -207
  248. package/lib/Utils/generics.js.map +1 -0
  249. package/lib/Utils/history.d.ts +16 -11
  250. package/lib/Utils/history.d.ts.map +1 -0
  251. package/lib/Utils/history.js +93 -53
  252. package/lib/Utils/history.js.map +1 -0
  253. package/lib/Utils/identity-change-handler.d.ts +44 -0
  254. package/lib/Utils/identity-change-handler.d.ts.map +1 -0
  255. package/lib/Utils/identity-change-handler.js +50 -0
  256. package/lib/Utils/identity-change-handler.js.map +1 -0
  257. package/lib/Utils/index.d.ts +30 -18
  258. package/lib/Utils/index.d.ts.map +1 -0
  259. package/lib/Utils/index.js +30 -34
  260. package/lib/Utils/index.js.map +1 -0
  261. package/lib/Utils/interactive.d.ts +60 -0
  262. package/lib/Utils/interactive.d.ts.map +1 -0
  263. package/lib/Utils/interactive.js +87 -117
  264. package/lib/Utils/interactive.js.map +1 -0
  265. package/lib/Utils/link-preview.d.ts +4 -4
  266. package/lib/Utils/link-preview.d.ts.map +1 -0
  267. package/lib/Utils/link-preview.js +17 -58
  268. package/lib/Utils/link-preview.js.map +1 -0
  269. package/lib/Utils/logger.d.ts +8 -6
  270. package/lib/Utils/logger.d.ts.map +1 -0
  271. package/lib/Utils/logger.js +3 -10
  272. package/lib/Utils/logger.js.map +1 -0
  273. package/lib/Utils/lt-hash.d.ts +8 -12
  274. package/lib/Utils/lt-hash.d.ts.map +1 -0
  275. package/lib/Utils/lt-hash.js +3 -46
  276. package/lib/Utils/lt-hash.js.map +1 -0
  277. package/lib/Utils/make-mutex.d.ts +2 -0
  278. package/lib/Utils/make-mutex.d.ts.map +1 -0
  279. package/lib/Utils/make-mutex.js +24 -34
  280. package/lib/Utils/make-mutex.js.map +1 -0
  281. package/lib/Utils/message-composer.d.ts +93 -0
  282. package/lib/Utils/message-composer.d.ts.map +1 -0
  283. package/lib/Utils/message-composer.js +311 -0
  284. package/lib/Utils/message-composer.js.map +1 -0
  285. package/lib/Utils/message-retry-manager.d.ts +115 -0
  286. package/lib/Utils/message-retry-manager.d.ts.map +1 -0
  287. package/lib/Utils/message-retry-manager.js +265 -0
  288. package/lib/Utils/message-retry-manager.js.map +1 -0
  289. package/lib/Utils/messages-media.d.ts +82 -40
  290. package/lib/Utils/messages-media.d.ts.map +1 -0
  291. package/lib/Utils/messages-media.js +674 -677
  292. package/lib/Utils/messages-media.js.map +1 -0
  293. package/lib/Utils/messages-newsletter.d.ts +74 -0
  294. package/lib/Utils/messages-newsletter.d.ts.map +1 -0
  295. package/lib/Utils/messages-newsletter.js +128 -0
  296. package/lib/Utils/messages-newsletter.js.map +1 -0
  297. package/lib/Utils/messages.d.ts +38 -14
  298. package/lib/Utils/messages.d.ts.map +1 -0
  299. package/lib/Utils/messages.js +835 -602
  300. package/lib/Utils/messages.js.map +1 -0
  301. package/lib/Utils/noise-handler.d.ts +9 -8
  302. package/lib/Utils/noise-handler.d.ts.map +1 -0
  303. package/lib/Utils/noise-handler.js +149 -98
  304. package/lib/Utils/noise-handler.js.map +1 -0
  305. package/lib/Utils/offline-node-processor.d.ts +17 -0
  306. package/lib/Utils/offline-node-processor.d.ts.map +1 -0
  307. package/lib/Utils/offline-node-processor.js +40 -0
  308. package/lib/Utils/offline-node-processor.js.map +1 -0
  309. package/lib/Utils/pre-key-manager.d.ts +28 -0
  310. package/lib/Utils/pre-key-manager.d.ts.map +1 -0
  311. package/lib/Utils/pre-key-manager.js +106 -0
  312. package/lib/Utils/pre-key-manager.js.map +1 -0
  313. package/lib/Utils/process-message.d.ts +30 -12
  314. package/lib/Utils/process-message.d.ts.map +1 -0
  315. package/lib/Utils/process-message.js +438 -230
  316. package/lib/Utils/process-message.js.map +1 -0
  317. package/lib/Utils/reporting-utils.d.ts +11 -0
  318. package/lib/Utils/reporting-utils.d.ts.map +1 -0
  319. package/lib/Utils/reporting-utils.js +258 -0
  320. package/lib/Utils/reporting-utils.js.map +1 -0
  321. package/lib/Utils/shortcake-crypto.d.ts +36 -0
  322. package/lib/Utils/shortcake-crypto.d.ts.map +1 -0
  323. package/lib/Utils/shortcake-crypto.js +71 -0
  324. package/lib/Utils/shortcake-crypto.js.map +1 -0
  325. package/lib/Utils/shortcake.d.ts +36 -0
  326. package/lib/Utils/shortcake.d.ts.map +1 -0
  327. package/lib/Utils/shortcake.js +162 -0
  328. package/lib/Utils/shortcake.js.map +1 -0
  329. package/lib/Utils/signal.d.ts +20 -6
  330. package/lib/Utils/signal.d.ts.map +1 -0
  331. package/lib/Utils/signal.js +112 -64
  332. package/lib/Utils/signal.js.map +1 -0
  333. package/lib/Utils/stanza-ack.d.ts +11 -0
  334. package/lib/Utils/stanza-ack.d.ts.map +1 -0
  335. package/lib/Utils/stanza-ack.js +38 -0
  336. package/lib/Utils/stanza-ack.js.map +1 -0
  337. package/lib/Utils/sync-action-utils.d.ts +19 -0
  338. package/lib/Utils/sync-action-utils.d.ts.map +1 -0
  339. package/lib/Utils/sync-action-utils.js +49 -0
  340. package/lib/Utils/sync-action-utils.js.map +1 -0
  341. package/lib/Utils/tc-token-utils.d.ts +37 -0
  342. package/lib/Utils/tc-token-utils.d.ts.map +1 -0
  343. package/lib/Utils/tc-token-utils.js +164 -0
  344. package/lib/Utils/tc-token-utils.js.map +1 -0
  345. package/lib/Utils/use-multi-file-auth-state.d.ts +2 -1
  346. package/lib/Utils/use-multi-file-auth-state.d.ts.map +1 -0
  347. package/lib/Utils/use-multi-file-auth-state.js +40 -64
  348. package/lib/Utils/use-multi-file-auth-state.js.map +1 -0
  349. package/lib/Utils/use-single-file-auth-state.d.ts +6 -0
  350. package/lib/Utils/use-single-file-auth-state.d.ts.map +1 -0
  351. package/lib/Utils/use-single-file-auth-state.js +111 -0
  352. package/lib/Utils/use-single-file-auth-state.js.map +1 -0
  353. package/lib/Utils/use-sqlite-auth-state.d.ts +14 -0
  354. package/lib/Utils/use-sqlite-auth-state.d.ts.map +1 -0
  355. package/lib/Utils/use-sqlite-auth-state.js +107 -0
  356. package/lib/Utils/use-sqlite-auth-state.js.map +1 -0
  357. package/lib/Utils/validate-connection.d.ts +5 -3
  358. package/lib/Utils/validate-connection.d.ts.map +1 -0
  359. package/lib/Utils/validate-connection.js +82 -101
  360. package/lib/Utils/validate-connection.js.map +1 -0
  361. package/lib/WABinary/constants.d.ts +1 -0
  362. package/lib/WABinary/constants.d.ts.map +1 -0
  363. package/lib/WABinary/constants.js +10 -12
  364. package/lib/WABinary/constants.js.map +1 -0
  365. package/lib/WABinary/decode.d.ts +2 -1
  366. package/lib/WABinary/decode.d.ts.map +1 -0
  367. package/lib/WABinary/decode.js +49 -52
  368. package/lib/WABinary/decode.js.map +1 -0
  369. package/lib/WABinary/encode.d.ts +2 -1
  370. package/lib/WABinary/encode.d.ts.map +1 -0
  371. package/lib/WABinary/encode.js +19 -49
  372. package/lib/WABinary/encode.js.map +1 -0
  373. package/lib/WABinary/generic-utils.d.ts +5 -4
  374. package/lib/WABinary/generic-utils.d.ts.map +1 -0
  375. package/lib/WABinary/generic-utils.js +46 -43
  376. package/lib/WABinary/generic-utils.js.map +1 -0
  377. package/lib/WABinary/index.d.ts +6 -5
  378. package/lib/WABinary/index.d.ts.map +1 -0
  379. package/lib/WABinary/index.js +6 -21
  380. package/lib/WABinary/index.js.map +1 -0
  381. package/lib/WABinary/jid-utils.d.ts +32 -10
  382. package/lib/WABinary/jid-utils.d.ts.map +1 -0
  383. package/lib/WABinary/jid-utils.js +103 -59
  384. package/lib/WABinary/jid-utils.js.map +1 -0
  385. package/lib/WABinary/types.d.ts +2 -1
  386. package/lib/WABinary/types.d.ts.map +1 -0
  387. package/lib/WABinary/types.js +2 -2
  388. package/lib/WABinary/types.js.map +1 -0
  389. package/lib/WAM/BinaryInfo.d.ts +2 -1
  390. package/lib/WAM/BinaryInfo.d.ts.map +1 -0
  391. package/lib/WAM/BinaryInfo.js +2 -5
  392. package/lib/WAM/BinaryInfo.js.map +1 -0
  393. package/lib/WAM/constants.d.ts +5 -3
  394. package/lib/WAM/constants.d.ts.map +1 -0
  395. package/lib/WAM/constants.js +19071 -11568
  396. package/lib/WAM/constants.js.map +1 -0
  397. package/lib/WAM/encode.d.ts +2 -1
  398. package/lib/WAM/encode.d.ts.map +1 -0
  399. package/lib/WAM/encode.js +17 -22
  400. package/lib/WAM/encode.js.map +1 -0
  401. package/lib/WAM/index.d.ts +4 -3
  402. package/lib/WAM/index.d.ts.map +1 -0
  403. package/lib/WAM/index.js +4 -19
  404. package/lib/WAM/index.js.map +1 -0
  405. package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +4 -3
  406. package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts.map +1 -0
  407. package/lib/WAUSync/Protocols/USyncContactProtocol.js +33 -13
  408. package/lib/WAUSync/Protocols/USyncContactProtocol.js.map +1 -0
  409. package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +3 -2
  410. package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts.map +1 -0
  411. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +11 -14
  412. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js.map +1 -0
  413. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +3 -2
  414. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts.map +1 -0
  415. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +8 -11
  416. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js.map +1 -0
  417. package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +3 -2
  418. package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts.map +1 -0
  419. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +9 -13
  420. package/lib/WAUSync/Protocols/USyncStatusProtocol.js.map +1 -0
  421. package/lib/WAUSync/Protocols/USyncUsernameProtocol.d.ts +10 -0
  422. package/lib/WAUSync/Protocols/USyncUsernameProtocol.d.ts.map +1 -0
  423. package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +25 -0
  424. package/lib/WAUSync/Protocols/USyncUsernameProtocol.js.map +1 -0
  425. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts +4 -3
  426. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts.map +1 -0
  427. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +20 -22
  428. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js.map +1 -0
  429. package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts +5 -3
  430. package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts.map +1 -0
  431. package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +13 -8
  432. package/lib/WAUSync/Protocols/UsyncLIDProtocol.js.map +1 -0
  433. package/lib/WAUSync/Protocols/index.d.ts +6 -4
  434. package/lib/WAUSync/Protocols/index.d.ts.map +1 -0
  435. package/lib/WAUSync/Protocols/index.js +6 -20
  436. package/lib/WAUSync/Protocols/index.js.map +1 -0
  437. package/lib/WAUSync/USyncQuery.d.ts +6 -4
  438. package/lib/WAUSync/USyncQuery.d.ts.map +1 -0
  439. package/lib/WAUSync/USyncQuery.js +44 -35
  440. package/lib/WAUSync/USyncQuery.js.map +1 -0
  441. package/lib/WAUSync/USyncUser.d.ts +10 -5
  442. package/lib/WAUSync/USyncUser.d.ts.map +1 -0
  443. package/lib/WAUSync/USyncUser.js +10 -5
  444. package/lib/WAUSync/USyncUser.js.map +1 -0
  445. package/lib/WAUSync/index.d.ts +4 -3
  446. package/lib/WAUSync/index.d.ts.map +1 -0
  447. package/lib/WAUSync/index.js +4 -19
  448. package/lib/WAUSync/index.js.map +1 -0
  449. package/lib/index.d.ts +12 -15
  450. package/lib/index.d.ts.map +1 -0
  451. package/lib/index.js +15 -48
  452. package/lib/index.js.map +1 -0
  453. package/package.json +44 -64
  454. package/WAProto/index.ts.ts +0 -53473
  455. package/WAProto/n +0 -1
  456. package/lib/Baileys.jpeg +0 -0
  457. package/lib/Defaults/baileys-version.json +0 -3
  458. package/lib/Defaults/n +0 -1
  459. package/lib/Signal/Group/queue-job.d.ts +0 -1
  460. package/lib/Signal/Group/queue-job.js +0 -57
  461. package/lib/Signal/n +0 -1
  462. package/lib/Socket/Client/n +0 -1
  463. package/lib/Socket/n +0 -1
  464. package/lib/Socket/setup.js +0 -480
  465. package/lib/Socket/setup.ts +0 -622
  466. package/lib/Socket/usync.d.ts +0 -36
  467. package/lib/Socket/usync.js +0 -70
  468. package/lib/Store/n +0 -1
  469. package/lib/Types/Newsletter.d.ts +0 -79
  470. package/lib/Types/Newsletter.js +0 -18
  471. package/lib/Types/n +0 -1
  472. package/lib/Utils/baileys-event-stream.d.ts +0 -16
  473. package/lib/Utils/baileys-event-stream.js +0 -63
  474. package/lib/Utils/error-handler.js +0 -37
  475. package/lib/Utils/n +0 -1
  476. package/lib/WABinary/jid-utils.js.bak +0 -83
  477. package/lib/WABinary/n +0 -1
  478. package/lib/WAM/n +0 -1
  479. package/lib/WAUSync/Protocols/n +0 -1
  480. package/lib/WAUSync/n +0 -1
  481. package/lib/n +0 -1
@@ -1,219 +1,340 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.makeSocket = void 0;
4
- const boom_1 = require("@hapi/boom");
5
- const crypto_1 = require("crypto");
6
- const url_1 = require("url");
7
- const util_1 = require("util");
8
- const WAProto_1 = require("../../WAProto");
9
- const Defaults_1 = require("../Defaults");
10
- const Types_1 = require("../Types");
11
- const Utils_1 = require("../Utils");
12
- const WABinary_1 = require("../WABinary");
13
- const Client_1 = require("./Client");
14
-
15
- const makeSocket = (config) => {
16
- var _a, _b;
17
- const { waWebSocketUrl, connectTimeoutMs, logger, keepAliveIntervalMs, browser, auth: authState, printQRInTerminal, defaultQueryTimeoutMs, transactionOpts, qrTimeout, makeSignalRepository, } = config;
18
- const url = typeof waWebSocketUrl === 'string' ? new url_1.URL(waWebSocketUrl) : waWebSocketUrl;
1
+ import { Boom } from '@hapi/boom';
2
+ import { randomBytes } from 'crypto';
3
+ import { URL } from 'url';
4
+ import { promisify } from 'util';
5
+ import { proto } from '../../WAProto/index.js';
6
+ import { DEF_CALLBACK_PREFIX, DEF_TAG_PREFIX, INITIAL_PREKEY_COUNT, MIN_PREKEY_COUNT, NOISE_WA_HEADER, PROCESSABLE_HISTORY_TYPES, TimeMs, UPLOAD_TIMEOUT } from '../Defaults/index.js';
7
+ import { QueryIds, ReachoutTimelockEnforcementType } from '../Types/index.js';
8
+ import { DisconnectReason, XWAPaths } from '../Types/index.js';
9
+ import { addTransactionCapability, aesEncryptCTR, bindWaitForConnectionUpdate, buildPairingQRData, bytesToCrockford, configureSuccessfulPairing, Curve, derivePairingCodeKey, generateLoginNode, generateMdTagPrefix, generateRegistrationNode, getCodeFromWSError, getCompanionPlatformId, getErrorCodeFromStreamError, getNextPreKeysNode, makeEventBuffer, makeNoiseHandler, promiseTimeout, signedKeyPair, xmppSignedPreKey } from '../Utils/index.js';
10
+ import { assertNodeErrorFree, binaryNodeToString, encodeBinaryNode, getAllBinaryNodeChildren, getBinaryNodeChild, getBinaryNodeChildren, isLidUser, jidDecode, jidEncode, S_WHATSAPP_NET } from '../WABinary/index.js';
11
+ import { BinaryInfo } from '../WAM/BinaryInfo.js';
12
+ import { USyncQuery, USyncUser } from '../WAUSync/index.js';
13
+ import { WebSocketClient } from './Client/index.js';
14
+ import { executeWMexQuery } from './mex.js';
15
+ /**
16
+ * Connects to WA servers and performs:
17
+ * - simple queries (no retry mechanism, wait for connection establishment)
18
+ * - listen to messages and emit events
19
+ * - query phone connection
20
+ */
21
+ export const makeSocket = (config) => {
22
+ const { waWebSocketUrl, connectTimeoutMs, logger, keepAliveIntervalMs, browser, auth: authState, printQRInTerminal, defaultQueryTimeoutMs, transactionOpts, qrTimeout, makeSignalRepository } = config;
23
+ const publicWAMBuffer = new BinaryInfo();
24
+ let serverTimeOffsetMs = 0;
25
+ const uqTagId = generateMdTagPrefix();
26
+ const generateMessageTag = () => `${uqTagId}${epoch++}`;
27
+ if (printQRInTerminal) {
28
+ logger.warn({}, '⚠️ The printQRInTerminal option has been deprecated. You will no longer receive QR codes in the terminal automatically. Please listen to the connection.update event yourself and handle the QR your way. You can remove this message by removing this opttion. This message will be removed in a future version.');
29
+ }
30
+ if (browser[1].toLocaleLowerCase().includes('android')) {
31
+ logger.warn('⚠️ Using the Android browser is experimental and may lead to unexpected behavior. Use at your own risk.');
32
+ }
33
+ const syncDisabled = PROCESSABLE_HISTORY_TYPES.map(syncType => config.shouldSyncHistoryMessage({ syncType })).filter(x => x === false)
34
+ .length === PROCESSABLE_HISTORY_TYPES.length;
35
+ if (syncDisabled) {
36
+ logger.warn('⚠️ DANGER: DISABLING ALL SYNC BY shouldSyncHistoryMsg PREVENTS BAILEYS FROM ACCESSING INITIAL LID MAPPINGS, LEADING TO INSTABILIY AND SESSION ERRORS');
37
+ }
38
+ const url = typeof waWebSocketUrl === 'string' ? new URL(waWebSocketUrl) : waWebSocketUrl;
19
39
  if (config.mobile || url.protocol === 'tcp:') {
20
- throw new boom_1.Boom('Mobile API is not supported anymore', { statusCode: Types_1.DisconnectReason.loggedOut });
40
+ throw new Boom('Mobile API is not supported anymore', { statusCode: DisconnectReason.loggedOut });
21
41
  }
22
- if (url.protocol === 'wss' && ((_a = authState === null || authState === void 0 ? void 0 : authState.creds) === null || _a === void 0 ? void 0 : _a.routingInfo)) {
42
+ if (url.protocol === 'wss' && authState?.creds?.routingInfo) {
23
43
  url.searchParams.append('ED', authState.creds.routingInfo.toString('base64url'));
24
44
  }
25
- const ws = new Client_1.WebSocketClient(url, config);
26
- ws.connect();
27
- const ev = (0, Utils_1.makeEventBuffer)(logger);
28
- const ephemeralKeyPair = Utils_1.Curve.generateKeyPair();
29
- const noise = (0, Utils_1.makeNoiseHandler)({
45
+ /** ephemeral key pair used to encrypt/decrypt communication. Unique for each connection */
46
+ const ephemeralKeyPair = Curve.generateKeyPair();
47
+ /** WA noise protocol wrapper */
48
+ const noise = makeNoiseHandler({
30
49
  keyPair: ephemeralKeyPair,
31
- NOISE_HEADER: Defaults_1.NOISE_WA_HEADER,
50
+ NOISE_HEADER: NOISE_WA_HEADER,
32
51
  logger,
33
- routingInfo: (_b = authState === null || authState === void 0 ? void 0 : authState.creds) === null || _b === void 0 ? void 0 : _b.routingInfo
52
+ routingInfo: authState?.creds?.routingInfo
34
53
  });
35
- const { creds } = authState;
36
- const keys = (0, Utils_1.addTransactionCapability)(authState.keys, logger, transactionOpts);
37
- const signalRepository = makeSignalRepository({ creds, keys });
38
- let lastDateRecv;
39
- let epoch = 1;
40
- let keepAliveReq;
41
- let qrTimer;
42
- let closed = false;
43
- const uqTagId = (0, Utils_1.generateMdTagPrefix)();
44
- const generateMessageTag = () => `${uqTagId}${epoch++}`;
45
- const sendPromise = (0, util_1.promisify)(ws.send);
46
-
54
+ const ws = new WebSocketClient(url, config);
55
+ ws.connect();
56
+ const sendPromise = promisify(ws.send);
57
+ /** send a raw buffer */
47
58
  const sendRawMessage = async (data) => {
48
- try {
49
- if (!ws.isOpen) {
50
- throw new boom_1.Boom('Connection Closed', { statusCode: Types_1.DisconnectReason.connectionClosed });
51
- }
52
- const bytes = noise.encodeFrame(data);
53
- await (0, Utils_1.promiseTimeout)(connectTimeoutMs, async (resolve, reject) => {
54
- try {
55
- await sendPromise.call(ws, bytes);
56
- resolve();
57
- }
58
- catch (error) {
59
- reject(error || new boom_1.Boom('Connection Closed', { statusCode: Types_1.DisconnectReason.connectionClosed }));
60
- }
61
- });
62
- } catch (err) {
63
- logger.error({ err }, 'Error in sendRawMessage');
64
- throw err;
65
- }
66
- };
67
-
68
- const sendNode = (frame) => {
69
- try {
70
- if (logger.level === 'trace') {
71
- logger.trace({ xml: (0, WABinary_1.binaryNodeToString)(frame), msg: 'xml send' });
72
- }
73
- const buff = (0, WABinary_1.encodeBinaryNode)(frame);
74
- return sendRawMessage(buff);
75
- } catch (error) {
76
- logger.error({ error }, 'Error sending node');
59
+ if (!ws.isOpen) {
60
+ throw new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed });
77
61
  }
78
- };
79
-
80
- // 🔧 REPARADO: Manejo mejorado de errores Bad MAC
81
- const onUnexpectedError = (err, msg) => {
82
- const errorMessage = (err && ((err.stack || err.message) || String(err))).toLowerCase();
83
-
84
- // Loggear el error pero no propagarlo si es de cifrado
85
- logger.error({ err }, `unexpected error in '${msg}'`);
86
-
87
- // Manejo específico para errores de MAC/criptografía - NO propagar estos errores
88
- if (errorMessage.includes('bad mac') ||
89
- (errorMessage.includes('mac') && errorMessage.includes('invalid')) ||
90
- errorMessage.includes('failed to decrypt') ||
91
- errorMessage.includes('session error') ||
92
- errorMessage.includes('libsignal')) {
93
-
94
- logger.warn('🔇 Error de cifrado detectado (Bad MAC/Session). Continuando conexión...');
95
-
62
+ const bytes = noise.encodeFrame(data);
63
+ await promiseTimeout(connectTimeoutMs, async (resolve, reject) => {
96
64
  try {
97
- // Re-subir prekeys para forzar nueva sincronización
98
- uploadPreKeysToServerIfRequired(true)
99
- .then(() => logger.info('✅ Prekeys re-subidas después de error MAC'))
100
- .catch(e => logger.warn({ e }, 'Fallo al re-subir prekeys'));
101
-
102
- } catch (cleanupErr) {
103
- logger.warn({ cleanupErr }, 'Error limpiando sesiones');
65
+ await sendPromise.call(ws, bytes);
66
+ resolve();
67
+ }
68
+ catch (error) {
69
+ reject(error);
104
70
  }
105
-
106
- // IMPORTANTE: No propagar el error si es solo de cifrado
107
- // Estos errores son recuperables y no deben cerrar la conexión
108
- return;
109
- }
110
-
111
- // Rate limiting
112
- if (errorMessage.includes('429') || errorMessage.includes('rate limit')) {
113
- const wait = Math.min(30000, (config.backoffDelayMs || 5000));
114
- logger.info({ wait }, 'backing off due to rate limit');
115
- setTimeout(() => { }, wait);
116
- }
117
- };
118
-
119
- const awaitNextMessage = async (sendMsg) => {
120
- if (!ws.isOpen) {
121
- throw new boom_1.Boom('Connection Closed', { statusCode: Types_1.DisconnectReason.connectionClosed });
122
- }
123
- let onOpen;
124
- let onClose;
125
- const result = (0, Utils_1.promiseTimeout)(connectTimeoutMs, (resolve, reject) => {
126
- onOpen = resolve;
127
- onClose = mapWebSocketError(reject);
128
- ws.on('frame', onOpen);
129
- ws.on('close', onClose);
130
- ws.on('error', onClose);
131
- })
132
- .finally(() => {
133
- ws.off('frame', onOpen);
134
- ws.off('close', onClose);
135
- ws.off('error', onClose);
136
71
  });
137
- if (sendMsg) {
138
- sendRawMessage(sendMsg).catch(err => {
139
- if (onClose) onClose(err);
140
- });
72
+ };
73
+ /** send a binary node */
74
+ const sendNode = (frame) => {
75
+ if (logger.level === 'trace') {
76
+ logger.trace({ xml: binaryNodeToString(frame), msg: 'xml send' });
141
77
  }
142
- return result;
78
+ const buff = encodeBinaryNode(frame);
79
+ return sendRawMessage(buff);
143
80
  };
144
-
81
+ /**
82
+ * Wait for a message with a certain tag to be received
83
+ * @param msgId the message tag to await
84
+ * @param timeoutMs timeout after which the promise will reject
85
+ */
145
86
  const waitForMessage = async (msgId, timeoutMs = defaultQueryTimeoutMs) => {
146
87
  let onRecv;
147
88
  let onErr;
148
89
  try {
149
- const result = await (0, Utils_1.promiseTimeout)(timeoutMs, (resolve, reject) => {
150
- onRecv = resolve;
90
+ const result = await promiseTimeout(timeoutMs, (resolve, reject) => {
91
+ onRecv = data => {
92
+ resolve(data);
93
+ };
151
94
  onErr = err => {
152
- reject(err || new boom_1.Boom('Connection Closed', { statusCode: Types_1.DisconnectReason.connectionClosed }));
95
+ reject(err ||
96
+ new Boom('Connection Closed', {
97
+ statusCode: DisconnectReason.connectionClosed
98
+ }));
153
99
  };
154
100
  ws.on(`TAG:${msgId}`, onRecv);
155
101
  ws.on('close', onErr);
156
102
  ws.on('error', onErr);
103
+ return () => reject(new Boom('Query Cancelled'));
157
104
  });
158
105
  return result;
159
106
  }
107
+ catch (error) {
108
+ // Catch timeout and return undefined instead of throwing
109
+ if (error instanceof Boom && error.output?.statusCode === DisconnectReason.timedOut) {
110
+ logger?.warn?.({ msgId }, 'timed out waiting for message');
111
+ return undefined;
112
+ }
113
+ throw error;
114
+ }
160
115
  finally {
161
- ws.off(`TAG:${msgId}`, onRecv);
162
- ws.off('close', onErr);
163
- ws.off('error', onErr);
116
+ if (onRecv)
117
+ ws.off(`TAG:${msgId}`, onRecv);
118
+ if (onErr) {
119
+ ws.off('close', onErr);
120
+ ws.off('error', onErr);
121
+ }
164
122
  }
165
123
  };
166
-
124
+ /** send a query, and wait for its response. auto-generates message ID if not provided */
167
125
  const query = async (node, timeoutMs) => {
168
126
  if (!node.attrs.id) {
169
127
  node.attrs.id = generateMessageTag();
170
128
  }
171
129
  const msgId = node.attrs.id;
172
- try {
173
- const [result] = await Promise.all([
174
- waitForMessage(msgId, timeoutMs),
175
- sendNode(node)
176
- ]);
177
- if (result && 'tag' in result) {
178
- (0, WABinary_1.assertNodeErrorFree)(result);
130
+ const result = await promiseTimeout(timeoutMs, async (resolve, reject) => {
131
+ const result = waitForMessage(msgId, timeoutMs).catch(reject);
132
+ sendNode(node)
133
+ .then(async () => resolve(await result))
134
+ .catch(reject);
135
+ });
136
+ if (result && 'tag' in result) {
137
+ assertNodeErrorFree(result);
138
+ }
139
+ return result;
140
+ };
141
+ // Validate current key-bundle on server; on failure, trigger pre-key upload and rethrow
142
+ const digestKeyBundle = async () => {
143
+ const res = await query({
144
+ tag: 'iq',
145
+ attrs: { to: S_WHATSAPP_NET, type: 'get', xmlns: 'encrypt' },
146
+ content: [{ tag: 'digest', attrs: {} }]
147
+ });
148
+ const digestNode = getBinaryNodeChild(res, 'digest');
149
+ if (!digestNode) {
150
+ await uploadPreKeys();
151
+ throw new Error('encrypt/get digest returned no digest node');
152
+ }
153
+ };
154
+ // Rotate our signed pre-key on server; on failure, run digest as fallback and rethrow
155
+ const rotateSignedPreKey = async () => {
156
+ const newId = (creds.signedPreKey.keyId || 0) + 1;
157
+ const skey = await signedKeyPair(creds.signedIdentityKey, newId);
158
+ await query({
159
+ tag: 'iq',
160
+ attrs: { to: S_WHATSAPP_NET, type: 'set', xmlns: 'encrypt' },
161
+ content: [
162
+ {
163
+ tag: 'rotate',
164
+ attrs: {},
165
+ content: [xmppSignedPreKey(skey)]
166
+ }
167
+ ]
168
+ });
169
+ // Persist new signed pre-key in creds
170
+ ev.emit('creds.update', { signedPreKey: skey });
171
+ };
172
+ const executeUSyncQuery = async (usyncQuery) => {
173
+ if (usyncQuery.protocols.length === 0) {
174
+ throw new Boom('USyncQuery must have at least one protocol');
175
+ }
176
+ // todo: validate users, throw WARNING on no valid users
177
+ // variable below has only validated users
178
+ const validUsers = usyncQuery.users;
179
+ const userNodes = validUsers.map(user => {
180
+ return {
181
+ tag: 'user',
182
+ attrs: {
183
+ jid: !user.phone ? user.id : undefined
184
+ },
185
+ content: usyncQuery.protocols.map(a => a.getUserElement(user)).filter(a => a !== null)
186
+ };
187
+ });
188
+ const listNode = {
189
+ tag: 'list',
190
+ attrs: {},
191
+ content: userNodes
192
+ };
193
+ const queryNode = {
194
+ tag: 'query',
195
+ attrs: {},
196
+ content: usyncQuery.protocols.map(a => a.getQueryElement())
197
+ };
198
+ const iq = {
199
+ tag: 'iq',
200
+ attrs: {
201
+ to: S_WHATSAPP_NET,
202
+ type: 'get',
203
+ xmlns: 'usync'
204
+ },
205
+ content: [
206
+ {
207
+ tag: 'usync',
208
+ attrs: {
209
+ context: usyncQuery.context,
210
+ mode: usyncQuery.mode,
211
+ sid: generateMessageTag(),
212
+ last: 'true',
213
+ index: '0'
214
+ },
215
+ content: [queryNode, listNode]
216
+ }
217
+ ]
218
+ };
219
+ const result = await query(iq);
220
+ return usyncQuery.parseUSyncQueryResult(result);
221
+ };
222
+ const onWhatsApp = async (...phoneNumber) => {
223
+ let usyncQuery = new USyncQuery();
224
+ let contactEnabled = false;
225
+ for (const jid of phoneNumber) {
226
+ if (isLidUser(jid)) {
227
+ logger?.warn('LIDs are not supported with onWhatsApp');
228
+ continue;
179
229
  }
180
- return result;
181
- } catch (error) {
182
- throw error;
230
+ else {
231
+ if (!contactEnabled) {
232
+ contactEnabled = true;
233
+ usyncQuery = usyncQuery.withContactProtocol();
234
+ }
235
+ const phone = `+${jid.replace('+', '').split('@')[0]?.split(':')[0]}`;
236
+ usyncQuery.withUser(new USyncUser().withPhone(phone));
237
+ }
238
+ }
239
+ if (usyncQuery.users.length === 0) {
240
+ return []; // return early without forcing an empty query
241
+ }
242
+ const results = await executeUSyncQuery(usyncQuery);
243
+ if (results) {
244
+ return results.list.filter(a => !!a.contact).map(({ contact, id }) => ({ jid: id, exists: contact }));
183
245
  }
184
246
  };
185
-
186
- const validateConnection = async () => {
187
- try {
188
- let helloMsg = { clientHello: { ephemeral: ephemeralKeyPair.public } };
189
- helloMsg = WAProto_1.proto.HandshakeMessage.fromObject(helloMsg);
190
- logger.info({ browser, helloMsg }, 'connected to WA');
191
- const init = WAProto_1.proto.HandshakeMessage.encode(helloMsg).finish();
192
- const result = await awaitNextMessage(init);
193
- const handshake = WAProto_1.proto.HandshakeMessage.decode(result);
194
- logger.trace({ handshake }, 'handshake recv from WA');
195
- const keyEnc = await noise.processHandshake(handshake, creds.noiseKey);
196
- let node;
197
- if (!creds.me) {
198
- node = (0, Utils_1.generateRegistrationNode)(creds, config);
199
- logger.info({ node }, 'not logged in, attempting registration...');
247
+ const pnFromLIDUSync = async (jids) => {
248
+ const usyncQuery = new USyncQuery().withLIDProtocol().withContext('background');
249
+ for (const jid of jids) {
250
+ if (isLidUser(jid)) {
251
+ logger?.warn('LID user found in LID fetch call');
252
+ continue;
200
253
  }
201
254
  else {
202
- node = (0, Utils_1.generateLoginNode)(creds.me.id, config);
203
- logger.info({ node }, 'logging in...');
255
+ usyncQuery.withUser(new USyncUser().withId(jid));
204
256
  }
205
- const payloadEnc = noise.encrypt(WAProto_1.proto.ClientPayload.encode(node).finish());
206
- await sendRawMessage(WAProto_1.proto.HandshakeMessage.encode({
207
- clientFinish: { static: keyEnc, payload: payloadEnc },
208
- }).finish());
209
- noise.finishInit();
210
- startKeepAliveRequest();
211
- } catch (err) {
212
- logger.error({ err }, 'error in validating connection');
213
- end(err);
214
257
  }
258
+ if (usyncQuery.users.length === 0) {
259
+ return []; // return early without forcing an empty query
260
+ }
261
+ const results = await executeUSyncQuery(usyncQuery);
262
+ if (results) {
263
+ return results.list.filter(a => !!a.lid).map(({ lid, id }) => ({ pn: id, lid: lid }));
264
+ }
265
+ return [];
266
+ };
267
+ const ev = makeEventBuffer(logger);
268
+ const { creds } = authState;
269
+ // add transaction capability
270
+ const keys = addTransactionCapability(authState.keys, logger, transactionOpts);
271
+ const signalRepository = makeSignalRepository({ creds, keys }, logger, pnFromLIDUSync);
272
+ let lastDateRecv;
273
+ let epoch = 1;
274
+ let keepAliveReq;
275
+ let qrTimer;
276
+ let closed = false;
277
+ const socketEndHandlers = [];
278
+ /** log & process any unexpected errors */
279
+ const onUnexpectedError = (err, msg) => {
280
+ logger.error({ err }, `unexpected error in '${msg}'`);
281
+ };
282
+ /** await the next incoming message */
283
+ const awaitNextMessage = async (sendMsg) => {
284
+ if (!ws.isOpen) {
285
+ throw new Boom('Connection Closed', {
286
+ statusCode: DisconnectReason.connectionClosed
287
+ });
288
+ }
289
+ let onOpen;
290
+ let onClose;
291
+ const result = promiseTimeout(connectTimeoutMs, (resolve, reject) => {
292
+ onOpen = resolve;
293
+ onClose = mapWebSocketError(reject);
294
+ ws.on('frame', onOpen);
295
+ ws.on('close', onClose);
296
+ ws.on('error', onClose);
297
+ }).finally(() => {
298
+ ws.off('frame', onOpen);
299
+ ws.off('close', onClose);
300
+ ws.off('error', onClose);
301
+ });
302
+ if (sendMsg) {
303
+ sendRawMessage(sendMsg).catch(onClose);
304
+ }
305
+ return result;
306
+ };
307
+ /** connection handshake */
308
+ const validateConnection = async () => {
309
+ let helloMsg = {
310
+ clientHello: { ephemeral: ephemeralKeyPair.public }
311
+ };
312
+ helloMsg = proto.HandshakeMessage.fromObject(helloMsg);
313
+ logger.info({ browser, helloMsg }, 'connected to WA');
314
+ const init = proto.HandshakeMessage.encode(helloMsg).finish();
315
+ const result = await awaitNextMessage(init);
316
+ const handshake = proto.HandshakeMessage.decode(result);
317
+ logger.trace({ handshake }, 'handshake recv from WA');
318
+ const keyEnc = noise.processHandshake(handshake, creds.noiseKey);
319
+ let node;
320
+ if (!creds.me) {
321
+ node = generateRegistrationNode(creds, config);
322
+ logger.info({ node }, 'not logged in, attempting registration...');
323
+ }
324
+ else {
325
+ node = generateLoginNode(creds.me.id, config);
326
+ logger.info({ node }, 'logging in...');
327
+ }
328
+ const payloadEnc = noise.encrypt(proto.ClientPayload.encode(node).finish());
329
+ await sendRawMessage(proto.HandshakeMessage.encode({
330
+ clientFinish: {
331
+ static: keyEnc,
332
+ payload: payloadEnc
333
+ }
334
+ }).finish());
335
+ await noise.finishInit();
336
+ startKeepAliveRequest();
215
337
  };
216
-
217
338
  const getAvailablePreKeysOnServer = async () => {
218
339
  const result = await query({
219
340
  tag: 'iq',
@@ -221,89 +342,176 @@ const makeSocket = (config) => {
221
342
  id: generateMessageTag(),
222
343
  xmlns: 'encrypt',
223
344
  type: 'get',
224
- to: WABinary_1.S_WHATSAPP_NET
345
+ to: S_WHATSAPP_NET
225
346
  },
226
347
  content: [{ tag: 'count', attrs: {} }]
227
348
  });
228
- const countChild = (0, WABinary_1.getBinaryNodeChild)(result, 'count');
349
+ const countChild = getBinaryNodeChild(result, 'count');
229
350
  return +countChild.attrs.value;
230
351
  };
231
-
232
- const uploadPreKeys = async (count = Defaults_1.INITIAL_PREKEY_COUNT) => {
233
- await keys.transaction(async () => {
234
- logger.info({ count }, 'uploading pre-keys');
235
- const { update, node } = await (0, Utils_1.getNextPreKeysNode)({ creds, keys }, count);
236
- await query(node);
237
- ev.emit('creds.update', update);
238
- logger.info({ count }, 'uploaded pre-keys');
239
- });
352
+ // WAWeb has no time throttle here; the server drives uploads via PreKeyLow notifications.
353
+ let uploadPreKeysPromise = null;
354
+ /** generates and uploads a set of pre-keys to the server */
355
+ const uploadPreKeys = async (count = MIN_PREKEY_COUNT) => {
356
+ if (uploadPreKeysPromise) {
357
+ logger.debug('Pre-key upload already in progress, waiting for completion');
358
+ await uploadPreKeysPromise;
359
+ return;
360
+ }
361
+ const uploadLogic = async (retryCount) => {
362
+ logger.info({ count, retryCount }, 'uploading pre-keys');
363
+ // Generate and save pre-keys atomically (prevents ID collisions on retry)
364
+ const node = await keys.transaction(async () => {
365
+ logger.debug({ requestedCount: count }, 'generating pre-keys with requested count');
366
+ const { update, node } = await getNextPreKeysNode({ creds, keys }, count);
367
+ // Update credentials immediately to prevent duplicate IDs on retry
368
+ ev.emit('creds.update', update);
369
+ return node;
370
+ }, creds?.me?.id || 'upload-pre-keys');
371
+ // Upload to server (outside transaction, can fail without affecting local keys)
372
+ try {
373
+ await query(node);
374
+ logger.info({ count }, 'uploaded pre-keys successfully');
375
+ }
376
+ catch (uploadError) {
377
+ logger.error({ uploadError: uploadError.toString(), count }, 'Failed to upload pre-keys to server');
378
+ // Recurse into uploadLogic; calling uploadPreKeys would await its own in-flight promise.
379
+ if (retryCount < 3) {
380
+ const backoffDelay = Math.min(1000 * Math.pow(2, retryCount), 10000);
381
+ logger.info(`Retrying pre-key upload in ${backoffDelay}ms`);
382
+ await new Promise(resolve => setTimeout(resolve, backoffDelay));
383
+ return uploadLogic(retryCount + 1);
384
+ }
385
+ throw uploadError;
386
+ }
387
+ };
388
+ // Add timeout protection
389
+ uploadPreKeysPromise = Promise.race([
390
+ uploadLogic(0),
391
+ new Promise((_, reject) => setTimeout(() => reject(new Boom('Pre-key upload timeout', { statusCode: 408 })), UPLOAD_TIMEOUT))
392
+ ]);
393
+ try {
394
+ await uploadPreKeysPromise;
395
+ }
396
+ finally {
397
+ uploadPreKeysPromise = null;
398
+ }
399
+ };
400
+ const verifyCurrentPreKeyExists = async () => {
401
+ const currentPreKeyId = creds.nextPreKeyId - 1;
402
+ if (currentPreKeyId <= 0) {
403
+ return { exists: false, currentPreKeyId: 0 };
404
+ }
405
+ const preKeys = await keys.get('pre-key', [currentPreKeyId.toString()]);
406
+ const exists = !!preKeys[currentPreKeyId.toString()];
407
+ return { exists, currentPreKeyId };
240
408
  };
241
-
242
- const uploadPreKeysToServerIfRequired = async (force = false) => {
409
+ const uploadPreKeysToServerIfRequired = async () => {
243
410
  try {
411
+ let count = 0;
244
412
  const preKeyCount = await getAvailablePreKeysOnServer();
413
+ if (preKeyCount === 0)
414
+ count = INITIAL_PREKEY_COUNT;
415
+ else
416
+ count = MIN_PREKEY_COUNT;
417
+ const { exists: currentPreKeyExists, currentPreKeyId } = await verifyCurrentPreKeyExists();
245
418
  logger.info(`${preKeyCount} pre-keys found on server`);
246
- if (force || preKeyCount <= Defaults_1.MIN_PREKEY_COUNT) {
247
- await uploadPreKeys();
419
+ logger.info(`Current prekey ID: ${currentPreKeyId}, exists in storage: ${currentPreKeyExists}`);
420
+ const lowServerCount = preKeyCount <= count;
421
+ const missingCurrentPreKey = !currentPreKeyExists && currentPreKeyId > 0;
422
+ const shouldUpload = lowServerCount || missingCurrentPreKey;
423
+ if (shouldUpload) {
424
+ const reasons = [];
425
+ if (lowServerCount)
426
+ reasons.push(`server count low (${preKeyCount})`);
427
+ if (missingCurrentPreKey)
428
+ reasons.push(`current prekey ${currentPreKeyId} missing from storage`);
429
+ logger.info(`Uploading PreKeys due to: ${reasons.join(', ')}`);
430
+ await uploadPreKeys(count);
248
431
  }
249
- } catch (err) {
250
- logger.warn({ err }, 'Error checking/uploading prekeys');
432
+ else {
433
+ logger.info(`PreKey validation passed - Server: ${preKeyCount}, Current prekey ${currentPreKeyId} exists`);
434
+ }
435
+ }
436
+ catch (error) {
437
+ logger.error({ error }, 'Failed to check/upload pre-keys during initialization');
438
+ // Don't throw - allow connection to continue even if pre-key check fails
251
439
  }
252
440
  };
253
-
254
- const onMessageReceived = (data) => {
255
- noise.decodeFrame(data, frame => {
256
- var _a;
441
+ const onMessageReceived = async (data) => {
442
+ await noise.decodeFrame(data, frame => {
443
+ // reset ping timeout
257
444
  lastDateRecv = new Date();
258
445
  let anyTriggered = false;
259
446
  anyTriggered = ws.emit('frame', frame);
447
+ // if it's a binary node
260
448
  if (!(frame instanceof Uint8Array)) {
261
449
  const msgId = frame.attrs.id;
262
450
  if (logger.level === 'trace') {
263
- logger.trace({ xml: (0, WABinary_1.binaryNodeToString)(frame), msg: 'recv xml' });
451
+ logger.trace({ xml: binaryNodeToString(frame), msg: 'recv xml' });
264
452
  }
265
- anyTriggered = ws.emit(`${Defaults_1.DEF_TAG_PREFIX}${msgId}`, frame) || anyTriggered;
453
+ /* Check if this is a response to a message we sent */
454
+ anyTriggered = ws.emit(`${DEF_TAG_PREFIX}${msgId}`, frame) || anyTriggered;
455
+ /* Check if this is a response to a message we are expecting */
266
456
  const l0 = frame.tag;
267
457
  const l1 = frame.attrs || {};
268
- const l2 = Array.isArray(frame.content) ? (_a = frame.content[0]) === null || _a === void 0 ? void 0 : _a.tag : '';
458
+ const l2 = Array.isArray(frame.content) ? frame.content[0]?.tag : '';
269
459
  for (const key of Object.keys(l1)) {
270
- anyTriggered = ws.emit(`${Defaults_1.DEF_CALLBACK_PREFIX}${l0},${key}:${l1[key]},${l2}`, frame) || anyTriggered;
271
- anyTriggered = ws.emit(`${Defaults_1.DEF_CALLBACK_PREFIX}${l0},${key}:${l1[key]}`, frame) || anyTriggered;
272
- anyTriggered = ws.emit(`${Defaults_1.DEF_CALLBACK_PREFIX}${l0},${key}`, frame) || anyTriggered;
460
+ anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0},${key}:${l1[key]},${l2}`, frame) || anyTriggered;
461
+ anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0},${key}:${l1[key]}`, frame) || anyTriggered;
462
+ anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0},${key}`, frame) || anyTriggered;
273
463
  }
274
- anyTriggered = ws.emit(`${Defaults_1.DEF_CALLBACK_PREFIX}${l0},,${l2}`, frame) || anyTriggered;
275
- anyTriggered = ws.emit(`${Defaults_1.DEF_CALLBACK_PREFIX}${l0}`, frame) || anyTriggered;
464
+ anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0},,${l2}`, frame) || anyTriggered;
465
+ anyTriggered = ws.emit(`${DEF_CALLBACK_PREFIX}${l0}`, frame) || anyTriggered;
276
466
  if (!anyTriggered && logger.level === 'debug') {
277
467
  logger.debug({ unhandled: true, msgId, fromMe: false, frame }, 'communication recv');
278
468
  }
279
469
  }
280
470
  });
281
471
  };
282
-
283
- const end = (error) => {
284
- if (closed) return;
472
+ const end = async (error) => {
473
+ if (closed) {
474
+ logger.trace({ trace: error?.stack }, 'connection already closed');
475
+ return;
476
+ }
285
477
  closed = true;
286
- logger.info({ trace: error === null || error === void 0 ? void 0 : error.stack }, error ? 'connection errored' : 'connection closed');
478
+ logger.info({ trace: error?.stack }, error ? 'connection errored' : 'connection closed');
287
479
  clearInterval(keepAliveReq);
288
480
  clearTimeout(qrTimer);
289
481
  ws.removeAllListeners('close');
290
- ws.removeAllListeners('error');
291
482
  ws.removeAllListeners('open');
292
483
  ws.removeAllListeners('message');
484
+ signalRepository.close?.();
293
485
  if (!ws.isClosed && !ws.isClosing) {
294
- try { ws.close(); } catch (_a) { }
486
+ try {
487
+ await ws.close();
488
+ }
489
+ catch { }
490
+ }
491
+ for (const handler of socketEndHandlers) {
492
+ try {
493
+ await handler(error);
494
+ }
495
+ catch (err) {
496
+ logger.error({ err }, 'error in socket end handler');
497
+ }
295
498
  }
296
499
  ev.emit('connection.update', {
297
500
  connection: 'close',
298
- lastDisconnect: { error, date: new Date() }
501
+ lastDisconnect: {
502
+ error,
503
+ date: new Date()
504
+ }
299
505
  });
300
506
  ev.removeAllListeners('connection.update');
507
+ ev.destroy();
301
508
  };
302
-
303
509
  const waitForSocketOpen = async () => {
304
- if (ws.isOpen) return;
510
+ if (ws.isOpen) {
511
+ return;
512
+ }
305
513
  if (ws.isClosed || ws.isClosing) {
306
- throw new boom_1.Boom('Connection Closed', { statusCode: Types_1.DisconnectReason.connectionClosed });
514
+ throw new Boom('Connection Closed', { statusCode: DisconnectReason.connectionClosed });
307
515
  }
308
516
  let onOpen;
309
517
  let onClose;
@@ -313,228 +521,418 @@ const makeSocket = (config) => {
313
521
  ws.on('open', onOpen);
314
522
  ws.on('close', onClose);
315
523
  ws.on('error', onClose);
316
- })
317
- .finally(() => {
524
+ }).finally(() => {
318
525
  ws.off('open', onOpen);
319
526
  ws.off('close', onClose);
320
527
  ws.off('error', onClose);
321
528
  });
322
529
  };
323
-
324
530
  const startKeepAliveRequest = () => (keepAliveReq = setInterval(() => {
325
- if (!lastDateRecv) lastDateRecv = new Date();
531
+ if (!lastDateRecv) {
532
+ lastDateRecv = new Date();
533
+ }
326
534
  const diff = Date.now() - lastDateRecv.getTime();
535
+ /*
536
+ check if it's been a suspicious amount of time since the server responded with our last seen
537
+ it could be that the network is down
538
+ */
327
539
  if (diff > keepAliveIntervalMs + 5000) {
328
- end(new boom_1.Boom('Connection was lost', { statusCode: Types_1.DisconnectReason.connectionLost }));
540
+ void end(new Boom('Connection was lost', { statusCode: DisconnectReason.connectionLost }));
329
541
  }
330
542
  else if (ws.isOpen) {
543
+ // if its all good, send a keep alive request
331
544
  query({
332
545
  tag: 'iq',
333
546
  attrs: {
334
547
  id: generateMessageTag(),
335
- to: WABinary_1.S_WHATSAPP_NET,
548
+ to: S_WHATSAPP_NET,
336
549
  type: 'get',
337
- xmlns: 'w:p',
550
+ xmlns: 'w:p'
338
551
  },
339
552
  content: [{ tag: 'ping', attrs: {} }]
340
553
  }).catch(err => {
341
554
  logger.error({ trace: err.stack }, 'error in sending keep alive');
342
555
  });
343
556
  }
557
+ else {
558
+ logger.warn('keep alive called when WS not open');
559
+ }
344
560
  }, keepAliveIntervalMs));
345
-
346
- const sendPassiveIq = (tag) => (query({
561
+ /** i have no idea why this exists. pls enlighten me */
562
+ const sendPassiveIq = (tag) => query({
347
563
  tag: 'iq',
348
- attrs: { to: WABinary_1.S_WHATSAPP_NET, xmlns: 'passive', type: 'set' },
564
+ attrs: {
565
+ to: S_WHATSAPP_NET,
566
+ xmlns: 'passive',
567
+ type: 'set'
568
+ },
349
569
  content: [{ tag, attrs: {} }]
350
- }));
351
-
570
+ });
571
+ /** logout & invalidate connection */
352
572
  const logout = async (msg) => {
353
- var _a;
354
- const jid = (_a = authState.creds.me) === null || _a === void 0 ? void 0 : _a.id;
573
+ const jid = authState.creds.me?.id;
355
574
  if (jid) {
356
575
  await sendNode({
357
576
  tag: 'iq',
358
- attrs: { to: WABinary_1.S_WHATSAPP_NET, type: 'set', id: generateMessageTag(), xmlns: 'md' },
359
- content: [{ tag: 'remove-companion-device', attrs: { jid, reason: 'user_initiated' } }]
360
- });
361
- }
362
- end(new boom_1.Boom(msg || 'Intentional Logout', { statusCode: Types_1.DisconnectReason.loggedOut }));
363
- };
364
-
365
- const requestPairingCode = async (phoneNumber, pairKey) => {
366
- try {
367
- if (!pairKey) {
368
- const randomSuffix = (0, crypto_1.randomBytes)(2).toString('hex').toUpperCase().slice(0, 4);
369
- pairKey = `ASTA${randomSuffix}`;
370
- }
371
- authState.creds.pairingCode = pairKey.toUpperCase();
372
- authState.creds.me = {
373
- id: (0, WABinary_1.jidEncode)(phoneNumber, 's.whatsapp.net'),
374
- name: '~'
375
- };
376
- ev.emit('creds.update', authState.creds);
377
- await sendNode({
378
- tag: 'iq',
379
- attrs: { to: WABinary_1.S_WHATSAPP_NET, type: 'set', id: generateMessageTag(), xmlns: 'md' },
577
+ attrs: {
578
+ to: S_WHATSAPP_NET,
579
+ type: 'set',
580
+ id: generateMessageTag(),
581
+ xmlns: 'md'
582
+ },
380
583
  content: [
381
584
  {
382
- tag: 'link_code_companion_reg',
585
+ tag: 'remove-companion-device',
383
586
  attrs: {
384
- jid: authState.creds.me.id,
385
- stage: 'companion_hello',
386
- should_show_push_notification: 'true'
387
- },
388
- content: [
389
- { tag: 'link_code_pairing_wrapped_companion_ephemeral_pub', attrs: {}, content: await generatePairingKey() },
390
- { tag: 'companion_server_auth_key_pub', attrs: {}, content: authState.creds.noiseKey.public },
391
- { tag: 'companion_platform_id', attrs: {}, content: (0, Utils_1.getPlatformId)(browser[1]) },
392
- { tag: 'companion_platform_display', attrs: {}, content: `${browser[1]} (${browser[0]})` },
393
- { tag: 'link_code_pairing_nonce', attrs: {}, content: '0' }
394
- ]
587
+ jid,
588
+ reason: 'user_initiated'
589
+ }
395
590
  }
396
591
  ]
397
592
  });
398
- return authState.creds.pairingCode;
399
- } catch (error) {
400
- logger.error({ error }, 'Error requesting pairing code');
401
- throw error;
402
593
  }
594
+ void end(new Boom(msg || 'Intentional Logout', { statusCode: DisconnectReason.loggedOut }));
595
+ };
596
+ const requestPairingCode = async (phoneNumber, customPairingCode) => {
597
+ // Por defecto usamos el código de marca "ASTABOTS" (8 caracteres) en vez de uno aleatorio,
598
+ // salvo que el llamador pase explícitamente su propio customPairingCode.
599
+ const pairingCode = customPairingCode ?? 'ASTABOTS';
600
+ if (customPairingCode && customPairingCode?.length !== 8) {
601
+ throw new Error('Custom pairing code must be exactly 8 chars');
602
+ }
603
+ authState.creds.pairingCode = pairingCode;
604
+ authState.creds.me = {
605
+ id: jidEncode(phoneNumber, 's.whatsapp.net'),
606
+ name: '~'
607
+ };
608
+ ev.emit('creds.update', authState.creds);
609
+ await sendNode({
610
+ tag: 'iq',
611
+ attrs: {
612
+ to: S_WHATSAPP_NET,
613
+ type: 'set',
614
+ id: generateMessageTag(),
615
+ xmlns: 'md'
616
+ },
617
+ content: [
618
+ {
619
+ tag: 'link_code_companion_reg',
620
+ attrs: {
621
+ jid: authState.creds.me.id,
622
+ stage: 'companion_hello',
623
+ should_show_push_notification: 'true'
624
+ },
625
+ content: [
626
+ {
627
+ tag: 'link_code_pairing_wrapped_companion_ephemeral_pub',
628
+ attrs: {},
629
+ content: await generatePairingKey()
630
+ },
631
+ {
632
+ tag: 'companion_server_auth_key_pub',
633
+ attrs: {},
634
+ content: authState.creds.noiseKey.public
635
+ },
636
+ {
637
+ tag: 'companion_platform_id',
638
+ attrs: {},
639
+ content: getCompanionPlatformId(browser)
640
+ },
641
+ {
642
+ tag: 'companion_platform_display',
643
+ attrs: {},
644
+ content: `${browser[1]} (${browser[0]})`
645
+ },
646
+ {
647
+ tag: 'link_code_pairing_nonce',
648
+ attrs: {},
649
+ content: '0'
650
+ }
651
+ ]
652
+ }
653
+ ]
654
+ });
655
+ return authState.creds.pairingCode;
403
656
  };
404
-
405
657
  async function generatePairingKey() {
406
- const salt = (0, crypto_1.randomBytes)(32);
407
- const randomIv = (0, crypto_1.randomBytes)(16);
408
- const key = await (0, Utils_1.derivePairingCodeKey)(authState.creds.pairingCode, salt);
409
- const ciphered = (0, Utils_1.aesEncryptCTR)(authState.creds.pairingEphemeralKeyPair.public, key, randomIv);
658
+ const salt = randomBytes(32);
659
+ const randomIv = randomBytes(16);
660
+ const key = await derivePairingCodeKey(authState.creds.pairingCode, salt);
661
+ const ciphered = aesEncryptCTR(authState.creds.pairingEphemeralKeyPair.public, key, randomIv);
410
662
  return Buffer.concat([salt, randomIv, ciphered]);
411
663
  }
412
-
413
664
  const sendWAMBuffer = (wamBuffer) => {
414
665
  return query({
415
666
  tag: 'iq',
416
- attrs: { to: WABinary_1.S_WHATSAPP_NET, id: generateMessageTag(), xmlns: 'w:stats' },
417
- content: [{ tag: 'add', attrs: {}, content: wamBuffer }]
667
+ attrs: {
668
+ to: S_WHATSAPP_NET,
669
+ id: generateMessageTag(),
670
+ xmlns: 'w:stats'
671
+ },
672
+ content: [
673
+ {
674
+ tag: 'add',
675
+ attrs: { t: Math.round(Date.now() / 1000) + '' },
676
+ content: wamBuffer
677
+ }
678
+ ]
418
679
  });
419
680
  };
420
-
421
681
  ws.on('message', onMessageReceived);
422
682
  ws.on('open', async () => {
423
- try { await validateConnection(); }
683
+ try {
684
+ await validateConnection();
685
+ }
424
686
  catch (err) {
425
687
  logger.error({ err }, 'error in validating connection');
426
- end(err);
688
+ void end(err);
427
689
  }
428
690
  });
429
691
  ws.on('error', mapWebSocketError(end));
430
- ws.on('close', () => end(new boom_1.Boom('Connection Terminated', { statusCode: Types_1.DisconnectReason.connectionClosed })));
431
- ws.on('CB:xmlstreamend', () => end(new boom_1.Boom('Connection Terminated by Server', { statusCode: Types_1.DisconnectReason.connectionClosed })));
432
-
692
+ ws.on('close', () => void end(new Boom('Connection Terminated', { statusCode: DisconnectReason.connectionClosed })));
693
+ // the server terminated the connection
694
+ ws.on('CB:xmlstreamend', () => void end(new Boom('Connection Terminated by Server', { statusCode: DisconnectReason.connectionClosed })));
695
+ // QR gen
433
696
  ws.on('CB:iq,type:set,pair-device', async (stanza) => {
434
- const iq = { tag: 'iq', attrs: { to: WABinary_1.S_WHATSAPP_NET, type: 'result', id: stanza.attrs.id } };
697
+ const iq = {
698
+ tag: 'iq',
699
+ attrs: {
700
+ to: S_WHATSAPP_NET,
701
+ type: 'result',
702
+ id: stanza.attrs.id
703
+ }
704
+ };
435
705
  await sendNode(iq);
436
- const pairDeviceNode = (0, WABinary_1.getBinaryNodeChild)(stanza, 'pair-device');
437
- const refNodes = (0, WABinary_1.getBinaryNodeChildren)(pairDeviceNode, 'ref');
706
+ const pairDeviceNode = getBinaryNodeChild(stanza, 'pair-device');
707
+ const refNodes = getBinaryNodeChildren(pairDeviceNode, 'ref');
438
708
  const noiseKeyB64 = Buffer.from(creds.noiseKey.public).toString('base64');
439
709
  const identityKeyB64 = Buffer.from(creds.signedIdentityKey.public).toString('base64');
440
710
  const advB64 = creds.advSecretKey;
441
- let qrMs = qrTimeout || 60000;
711
+ let qrMs = qrTimeout || 60000; // time to let a QR live
442
712
  const genPairQR = () => {
443
- if (!ws.isOpen) return;
713
+ if (!ws.isOpen) {
714
+ return;
715
+ }
444
716
  const refNode = refNodes.shift();
445
717
  if (!refNode) {
446
- end(new boom_1.Boom('QR refs attempts ended', { statusCode: Types_1.DisconnectReason.timedOut }));
718
+ void end(new Boom('QR refs attempts ended', { statusCode: DisconnectReason.timedOut }));
447
719
  return;
448
720
  }
449
721
  const ref = refNode.content.toString('utf-8');
450
- const qr = [ref, noiseKeyB64, identityKeyB64, advB64].join(',');
722
+ const qr = buildPairingQRData(ref, noiseKeyB64, identityKeyB64, advB64, browser);
451
723
  ev.emit('connection.update', { qr });
452
724
  qrTimer = setTimeout(genPairQR, qrMs);
453
- qrMs = qrTimeout || 20000;
725
+ qrMs = qrTimeout || 20000; // shorter subsequent qrs
454
726
  };
455
727
  genPairQR();
456
728
  });
457
-
729
+ // device paired for the first time
730
+ // if device pairs successfully, the server asks to restart the connection
458
731
  ws.on('CB:iq,,pair-success', async (stanza) => {
732
+ logger.debug('pair success recv');
459
733
  try {
460
- const { reply, creds: updatedCreds } = (0, Utils_1.configureSuccessfulPairing)(stanza, creds);
734
+ updateServerTimeOffset(stanza);
735
+ const { reply, creds: updatedCreds } = configureSuccessfulPairing(stanza, creds);
736
+ logger.info({ me: updatedCreds.me, platform: updatedCreds.platform }, 'pairing configured successfully, expect to restart the connection...');
461
737
  ev.emit('creds.update', updatedCreds);
462
738
  ev.emit('connection.update', { isNewLogin: true, qr: undefined });
463
739
  await sendNode(reply);
740
+ void sendUnifiedSession();
464
741
  }
465
742
  catch (error) {
466
- end(error);
743
+ logger.info({ trace: error.stack }, 'error in pairing');
744
+ void end(error);
467
745
  }
468
746
  });
469
-
747
+ // login complete
470
748
  ws.on('CB:success', async (node) => {
471
749
  try {
750
+ updateServerTimeOffset(node);
472
751
  await uploadPreKeysToServerIfRequired();
473
752
  await sendPassiveIq('active');
474
- clearTimeout(qrTimer);
475
- ev.emit('creds.update', { me: { ...authState.creds.me, lid: node.attrs.lid } });
476
- ev.emit('connection.update', { connection: 'open' });
753
+ // After successful login, validate our key-bundle against server
754
+ try {
755
+ await digestKeyBundle();
756
+ }
757
+ catch (e) {
758
+ logger.warn({ e }, 'failed to run digest after login');
759
+ }
477
760
  }
478
761
  catch (err) {
479
- end(err);
762
+ logger.warn({ err }, 'failed to send initial passive iq');
763
+ }
764
+ logger.info('opened connection to WA');
765
+ clearTimeout(qrTimer); // will never happen in all likelyhood -- but just in case WA sends success on first try
766
+ ev.emit('creds.update', { me: { ...authState.creds.me, lid: node.attrs.lid } });
767
+ ev.emit('connection.update', { connection: 'open' });
768
+ void sendUnifiedSession();
769
+ if (node.attrs.lid && authState.creds.me?.id) {
770
+ const myLID = node.attrs.lid;
771
+ process.nextTick(async () => {
772
+ try {
773
+ const myPN = authState.creds.me.id;
774
+ // Store our own LID-PN mapping
775
+ await signalRepository.lidMapping.storeLIDPNMappings([{ lid: myLID, pn: myPN }]);
776
+ // Create device list for our own user (needed for bulk migration)
777
+ const { user, device } = jidDecode(myPN);
778
+ await authState.keys.set({
779
+ 'device-list': {
780
+ [user]: [device?.toString() || '0']
781
+ }
782
+ });
783
+ // migrate our own session
784
+ await signalRepository.migrateSession(myPN, myLID);
785
+ logger.info({ myPN, myLID }, 'Own LID session created successfully');
786
+ }
787
+ catch (error) {
788
+ logger.error({ error, lid: myLID }, 'Failed to create own LID session');
789
+ }
790
+ });
480
791
  }
481
792
  });
482
-
483
793
  ws.on('CB:stream:error', (node) => {
484
- const { reason, statusCode } = (0, Utils_1.getErrorCodeFromStreamError)(node);
485
- end(new boom_1.Boom(`Stream Errored (${reason})`, { statusCode, data: node }));
794
+ const [reasonNode] = getAllBinaryNodeChildren(node);
795
+ logger.error({ reasonNode, fullErrorNode: node }, 'stream errored out');
796
+ const { reason, statusCode } = getErrorCodeFromStreamError(node);
797
+ void end(new Boom(`Stream Errored (${reason})`, { statusCode, data: reasonNode || node }));
486
798
  });
487
-
799
+ // stream fail, possible logout
488
800
  ws.on('CB:failure', (node) => {
489
801
  const reason = +(node.attrs.reason || 500);
490
- end(new boom_1.Boom('Connection Failure', { statusCode: reason, data: node.attrs }));
802
+ void end(new Boom('Connection Failure', { statusCode: reason, data: node.attrs }));
803
+ });
804
+ ws.on('CB:ib,,downgrade_webclient', () => {
805
+ void end(new Boom('Multi-device beta not joined', { statusCode: DisconnectReason.multideviceMismatch }));
806
+ });
807
+ ws.on('CB:ib,,offline_preview', async (node) => {
808
+ logger.info('offline preview received', JSON.stringify(node));
809
+ await sendNode({
810
+ tag: 'ib',
811
+ attrs: {},
812
+ content: [{ tag: 'offline_batch', attrs: { count: '100' } }]
813
+ });
491
814
  });
492
-
493
815
  ws.on('CB:ib,,edge_routing', (node) => {
494
- const edgeRoutingNode = (0, WABinary_1.getBinaryNodeChild)(node, 'edge_routing');
495
- const routingInfo = (0, WABinary_1.getBinaryNodeChild)(edgeRoutingNode, 'routing_info');
496
- if (routingInfo === null || routingInfo === void 0 ? void 0 : routingInfo.content) {
497
- authState.creds.routingInfo = Buffer.from(routingInfo === null || routingInfo === void 0 ? void 0 : routingInfo.content);
816
+ const edgeRoutingNode = getBinaryNodeChild(node, 'edge_routing');
817
+ const routingInfo = getBinaryNodeChild(edgeRoutingNode, 'routing_info');
818
+ if (routingInfo?.content) {
819
+ authState.creds.routingInfo = Buffer.from(routingInfo?.content);
498
820
  ev.emit('creds.update', authState.creds);
499
821
  }
500
822
  });
501
-
502
823
  let didStartBuffer = false;
503
824
  process.nextTick(() => {
504
- var _a;
505
- if ((_a = creds.me) === null || _a === void 0 ? void 0 : _a.id) {
825
+ if (creds.me?.id) {
826
+ // start buffering important events
827
+ // if we're logged in
506
828
  ev.buffer();
507
829
  didStartBuffer = true;
508
830
  }
509
831
  ev.emit('connection.update', { connection: 'connecting', receivedPendingNotifications: false, qr: undefined });
510
832
  });
511
-
833
+ // called when all offline notifs are handled
512
834
  ws.on('CB:ib,,offline', (node) => {
513
- const child = (0, WABinary_1.getBinaryNodeChild)(node, 'offline');
514
- const offlineNotifs = +((child === null || child === void 0 ? void 0 : child.attrs.count) || 0);
515
- if (didStartBuffer) ev.flush();
835
+ const child = getBinaryNodeChild(node, 'offline');
836
+ const offlineNotifs = +(child?.attrs.count || 0);
837
+ logger.info(`handled ${offlineNotifs} offline messages/notifications`);
838
+ if (didStartBuffer) {
839
+ ev.flush();
840
+ logger.trace('flushed events for initial buffer');
841
+ }
516
842
  ev.emit('connection.update', { receivedPendingNotifications: true });
517
843
  });
518
-
844
+ // update credentials when required
519
845
  ev.on('creds.update', update => {
520
- var _a, _b;
521
- const name = (_a = update.me) === null || _a === void 0 ? void 0 : _a.name;
522
- if (((_b = creds.me) === null || _b === void 0 ? void 0 : _b.name) !== name) {
523
- sendNode({ tag: 'presence', attrs: { name: name } })
524
- .catch(err => logger.warn({ trace: err.stack }, 'presence error'));
846
+ const name = update.me?.name;
847
+ // if name has just been received
848
+ if (creds.me?.name !== name) {
849
+ logger.debug({ name }, 'updated pushName');
850
+ sendNode({
851
+ tag: 'presence',
852
+ attrs: { name: name }
853
+ }).catch(err => {
854
+ logger.warn({ trace: err.stack }, 'error in sending presence update on name change');
855
+ });
525
856
  }
526
857
  Object.assign(creds, update);
527
858
  });
528
-
529
- if (printQRInTerminal) (0, Utils_1.printQRIfNecessaryListener)(ev, logger);
530
-
859
+ const updateServerTimeOffset = ({ attrs }) => {
860
+ const tValue = attrs?.t;
861
+ if (!tValue) {
862
+ return;
863
+ }
864
+ const parsed = Number(tValue);
865
+ if (Number.isNaN(parsed) || parsed <= 0) {
866
+ return;
867
+ }
868
+ const localMs = Date.now();
869
+ serverTimeOffsetMs = parsed * 1000 - localMs;
870
+ logger.debug({ offset: serverTimeOffsetMs }, 'calculated server time offset');
871
+ };
872
+ const getUnifiedSessionId = () => {
873
+ const offsetMs = 3 * TimeMs.Day;
874
+ const now = Date.now() + serverTimeOffsetMs;
875
+ const id = (now + offsetMs) % TimeMs.Week;
876
+ return id.toString();
877
+ };
878
+ const sendUnifiedSession = async () => {
879
+ if (!ws.isOpen) {
880
+ return;
881
+ }
882
+ const node = {
883
+ tag: 'ib',
884
+ attrs: {},
885
+ content: [
886
+ {
887
+ tag: 'unified_session',
888
+ attrs: {
889
+ id: getUnifiedSessionId()
890
+ }
891
+ }
892
+ ]
893
+ };
894
+ try {
895
+ await sendNode(node);
896
+ }
897
+ catch (error) {
898
+ logger.debug({ error }, 'failed to send unified_session telemetry');
899
+ }
900
+ };
901
+ const registerSocketEndHandler = (handler) => {
902
+ socketEndHandlers.push(handler);
903
+ };
904
+ /**
905
+ * Fetches your account's standing when it comes to restrictions.
906
+ * @returns Returns the state of the restrictions.
907
+ */
908
+ const fetchAccountReachoutTimelock = async () => {
909
+ const queryResult = await executeWMexQuery({}, QueryIds.REACHOUT_TIMELOCK, XWAPaths.xwa2_fetch_account_reachout_timelock, query, generateMessageTag);
910
+ const result = {
911
+ isActive: !!queryResult?.is_active,
912
+ timeEnforcementEnds: queryResult?.time_enforcement_ends && queryResult?.time_enforcement_ends !== '0'
913
+ ? new Date(parseInt(queryResult.time_enforcement_ends, 10) * 1000)
914
+ : undefined,
915
+ enforcementType: queryResult?.enforcement_type ?? ReachoutTimelockEnforcementType.DEFAULT
916
+ };
917
+ ev.emit('connection.update', { reachoutTimeLock: result });
918
+ return result;
919
+ };
920
+ /**
921
+ * Fetches your account's new chat limits.
922
+ * @returns Returns the quota and the usage.
923
+ */
924
+ const fetchNewChatMessageCap = async () => {
925
+ return executeWMexQuery({ input: { type: 'INDIVIDUAL_NEW_CHAT_MSG' } }, QueryIds.MESSAGE_CAPPING_INFO, XWAPaths.xwa2_message_capping_info, query, generateMessageTag);
926
+ };
531
927
  return {
532
928
  type: 'md',
533
929
  ws,
534
930
  ev,
535
931
  authState: { creds, keys },
536
932
  signalRepository,
537
- get user() { return authState.creds.me; },
933
+ get user() {
934
+ return authState.creds.me;
935
+ },
538
936
  generateMessageTag,
539
937
  query,
540
938
  waitForMessage,
@@ -543,18 +941,32 @@ const makeSocket = (config) => {
543
941
  sendNode,
544
942
  logout,
545
943
  end,
944
+ registerSocketEndHandler,
546
945
  onUnexpectedError,
547
946
  uploadPreKeys,
548
947
  uploadPreKeysToServerIfRequired,
948
+ digestKeyBundle,
949
+ rotateSignedPreKey,
549
950
  requestPairingCode,
550
- waitForConnectionUpdate: (0, Utils_1.bindWaitForConnectionUpdate)(ev),
951
+ updateServerTimeOffset,
952
+ sendUnifiedSession,
953
+ wamBuffer: publicWAMBuffer,
954
+ /** Waits for the connection to WA to reach a state */
955
+ waitForConnectionUpdate: bindWaitForConnectionUpdate(ev),
551
956
  sendWAMBuffer,
957
+ executeUSyncQuery,
958
+ onWhatsApp,
959
+ fetchAccountReachoutTimelock,
960
+ fetchNewChatMessageCap
552
961
  };
553
962
  };
554
- exports.makeSocket = makeSocket;
555
-
963
+ /**
964
+ * map the websocket error to the right type
965
+ * so it can be retried by the caller
966
+ * */
556
967
  function mapWebSocketError(handler) {
557
968
  return (error) => {
558
- handler(new boom_1.Boom(`WebSocket Error (${error === null || error === void 0 ? void 0 : error.message})`, { statusCode: (0, Utils_1.getCodeFromWSError)(error), data: error }));
969
+ handler(new Boom(`WebSocket Error (${error?.message})`, { statusCode: getCodeFromWSError(error), data: error }));
559
970
  };
560
971
  }
972
+ //# sourceMappingURL=socket.js.map