zapo-js 0.1.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 (585) hide show
  1. package/README.md +235 -0
  2. package/dist/appstate/WaAppStateCrypto.js +202 -0
  3. package/dist/appstate/WaAppStateSyncClient.js +808 -0
  4. package/dist/appstate/WaAppStateSyncResponseParser.js +71 -0
  5. package/dist/appstate/constants.js +23 -0
  6. package/dist/appstate/index.js +28 -0
  7. package/dist/appstate/store/sqlite.js +55 -0
  8. package/dist/appstate/types.js +2 -0
  9. package/dist/appstate/utils.js +84 -0
  10. package/dist/auth/WaAuthClient.js +266 -0
  11. package/dist/auth/flow/WaAuthCredentialsFlow.js +123 -0
  12. package/dist/auth/index.js +27 -0
  13. package/dist/auth/pairing/WaPairingCodeCrypto.js +75 -0
  14. package/dist/auth/pairing/WaPairingFlow.js +328 -0
  15. package/dist/auth/pairing/WaQrFlow.js +86 -0
  16. package/dist/auth/pairing/constants.js +5 -0
  17. package/dist/auth/types.js +2 -0
  18. package/dist/client/WaClient.js +749 -0
  19. package/dist/client/WaClientFactory.js +381 -0
  20. package/dist/client/coordinators/WaGroupCoordinator.js +191 -0
  21. package/dist/client/coordinators/WaIncomingNodeCoordinator.js +315 -0
  22. package/dist/client/coordinators/WaMessageDispatchCoordinator.js +1061 -0
  23. package/dist/client/coordinators/WaPassiveTasksCoordinator.js +200 -0
  24. package/dist/client/coordinators/WaRetryCoordinator.js +494 -0
  25. package/dist/client/coordinators/WaStreamControlCoordinator.js +123 -0
  26. package/dist/client/dirty.js +254 -0
  27. package/dist/client/events/chat.js +226 -0
  28. package/dist/client/events/group.js +410 -0
  29. package/dist/client/history-sync.js +122 -0
  30. package/dist/client/incoming.js +236 -0
  31. package/dist/client/index.js +5 -0
  32. package/dist/client/mailbox.js +49 -0
  33. package/dist/client/messages.js +152 -0
  34. package/dist/client/types.js +2 -0
  35. package/dist/crypto/core/constants.js +4 -0
  36. package/dist/crypto/core/encoding.js +29 -0
  37. package/dist/crypto/core/hkdf.js +26 -0
  38. package/dist/crypto/core/index.js +43 -0
  39. package/dist/crypto/core/keys.js +73 -0
  40. package/dist/crypto/core/nonce.js +18 -0
  41. package/dist/crypto/core/primitives.js +121 -0
  42. package/dist/crypto/core/random.js +32 -0
  43. package/dist/crypto/curves/Ed25519.js +42 -0
  44. package/dist/crypto/curves/X25519.js +64 -0
  45. package/dist/crypto/curves/constants.js +6 -0
  46. package/dist/crypto/curves/types.js +9 -0
  47. package/dist/crypto/index.js +22 -0
  48. package/dist/crypto/math/constants.js +44 -0
  49. package/dist/crypto/math/edwards.js +64 -0
  50. package/dist/crypto/math/le.js +20 -0
  51. package/dist/crypto/math/mod.js +38 -0
  52. package/dist/crypto/math/types.js +2 -0
  53. package/dist/esm/appstate/WaAppStateCrypto.js +198 -0
  54. package/dist/esm/appstate/WaAppStateSyncClient.js +803 -0
  55. package/dist/esm/appstate/WaAppStateSyncResponseParser.js +67 -0
  56. package/dist/esm/appstate/constants.js +20 -0
  57. package/dist/esm/appstate/index.js +6 -0
  58. package/dist/esm/appstate/store/sqlite.js +49 -0
  59. package/dist/esm/appstate/types.js +1 -0
  60. package/dist/esm/appstate/utils.js +75 -0
  61. package/dist/esm/auth/WaAuthClient.js +262 -0
  62. package/dist/esm/auth/flow/WaAuthCredentialsFlow.js +118 -0
  63. package/dist/esm/auth/index.js +5 -0
  64. package/dist/esm/auth/pairing/WaPairingCodeCrypto.js +71 -0
  65. package/dist/esm/auth/pairing/WaPairingFlow.js +324 -0
  66. package/dist/esm/auth/pairing/WaQrFlow.js +82 -0
  67. package/dist/esm/auth/pairing/constants.js +2 -0
  68. package/dist/esm/auth/types.js +1 -0
  69. package/dist/esm/client/WaClient.js +745 -0
  70. package/dist/esm/client/WaClientFactory.js +377 -0
  71. package/dist/esm/client/coordinators/WaGroupCoordinator.js +188 -0
  72. package/dist/esm/client/coordinators/WaIncomingNodeCoordinator.js +311 -0
  73. package/dist/esm/client/coordinators/WaMessageDispatchCoordinator.js +1057 -0
  74. package/dist/esm/client/coordinators/WaPassiveTasksCoordinator.js +196 -0
  75. package/dist/esm/client/coordinators/WaRetryCoordinator.js +490 -0
  76. package/dist/esm/client/coordinators/WaStreamControlCoordinator.js +120 -0
  77. package/dist/esm/client/dirty.js +250 -0
  78. package/dist/esm/client/events/chat.js +223 -0
  79. package/dist/esm/client/events/group.js +407 -0
  80. package/dist/esm/client/history-sync.js +119 -0
  81. package/dist/esm/client/incoming.js +227 -0
  82. package/dist/esm/client/index.js +1 -0
  83. package/dist/esm/client/mailbox.js +46 -0
  84. package/dist/esm/client/messages.js +148 -0
  85. package/dist/esm/client/types.js +1 -0
  86. package/dist/esm/crypto/core/constants.js +1 -0
  87. package/dist/esm/crypto/core/encoding.js +25 -0
  88. package/dist/esm/crypto/core/hkdf.js +22 -0
  89. package/dist/esm/crypto/core/index.js +11 -0
  90. package/dist/esm/crypto/core/keys.js +66 -0
  91. package/dist/esm/crypto/core/nonce.js +15 -0
  92. package/dist/esm/crypto/core/primitives.js +102 -0
  93. package/dist/esm/crypto/core/random.js +28 -0
  94. package/dist/esm/crypto/curves/Ed25519.js +38 -0
  95. package/dist/esm/crypto/curves/X25519.js +58 -0
  96. package/dist/esm/crypto/curves/constants.js +3 -0
  97. package/dist/esm/crypto/curves/types.js +6 -0
  98. package/dist/esm/crypto/index.js +3 -0
  99. package/dist/esm/crypto/math/constants.js +41 -0
  100. package/dist/esm/crypto/math/edwards.js +60 -0
  101. package/dist/esm/crypto/math/le.js +16 -0
  102. package/dist/esm/crypto/math/mod.js +31 -0
  103. package/dist/esm/crypto/math/types.js +1 -0
  104. package/dist/esm/index.js +6 -0
  105. package/dist/esm/infra/log/ConsoleLogger.js +40 -0
  106. package/dist/esm/infra/log/PinoLogger.js +73 -0
  107. package/dist/esm/infra/log/types.js +1 -0
  108. package/dist/esm/infra/perf/BoundedTaskQueue.js +62 -0
  109. package/dist/esm/media/WaMediaCrypto.js +224 -0
  110. package/dist/esm/media/WaMediaTransferClient.js +361 -0
  111. package/dist/esm/media/conn.js +33 -0
  112. package/dist/esm/media/constants.js +18 -0
  113. package/dist/esm/media/index.js +3 -0
  114. package/dist/esm/media/types.js +1 -0
  115. package/dist/esm/message/WaMessageClient.js +210 -0
  116. package/dist/esm/message/ack.js +46 -0
  117. package/dist/esm/message/content.js +20 -0
  118. package/dist/esm/message/device-sent.js +49 -0
  119. package/dist/esm/message/incoming.js +318 -0
  120. package/dist/esm/message/index.js +2 -0
  121. package/dist/esm/message/padding.js +20 -0
  122. package/dist/esm/message/phash.js +25 -0
  123. package/dist/esm/message/types.js +1 -0
  124. package/dist/esm/package.json +3 -0
  125. package/dist/esm/proto.js +3 -0
  126. package/dist/esm/protocol/appstate.js +34 -0
  127. package/dist/esm/protocol/auth.js +12 -0
  128. package/dist/esm/protocol/browser.js +41 -0
  129. package/dist/esm/protocol/constants.js +11 -0
  130. package/dist/esm/protocol/defaults.js +27 -0
  131. package/dist/esm/protocol/dirty.js +26 -0
  132. package/dist/esm/protocol/group.js +5 -0
  133. package/dist/esm/protocol/index.js +11 -0
  134. package/dist/esm/protocol/jid.js +94 -0
  135. package/dist/esm/protocol/media.js +20 -0
  136. package/dist/esm/protocol/message.js +16 -0
  137. package/dist/esm/protocol/nodes.js +83 -0
  138. package/dist/esm/protocol/notification.js +50 -0
  139. package/dist/esm/protocol/stream.js +60 -0
  140. package/dist/esm/retry/constants.js +20 -0
  141. package/dist/esm/retry/index.js +5 -0
  142. package/dist/esm/retry/outbound.js +83 -0
  143. package/dist/esm/retry/parse.js +130 -0
  144. package/dist/esm/retry/reason.js +50 -0
  145. package/dist/esm/retry/replay.js +177 -0
  146. package/dist/esm/retry/types.js +1 -0
  147. package/dist/esm/signal/api/SignalDeviceSyncApi.js +185 -0
  148. package/dist/esm/signal/api/SignalDigestSyncApi.js +179 -0
  149. package/dist/esm/signal/api/SignalIdentitySyncApi.js +111 -0
  150. package/dist/esm/signal/api/SignalMissingPreKeysSyncApi.js +141 -0
  151. package/dist/esm/signal/api/SignalRotateKeyApi.js +59 -0
  152. package/dist/esm/signal/api/SignalSessionSyncApi.js +187 -0
  153. package/dist/esm/signal/api/codec.js +23 -0
  154. package/dist/esm/signal/api/constants.js +9 -0
  155. package/dist/esm/signal/api/prekeys.js +9 -0
  156. package/dist/esm/signal/constants.js +16 -0
  157. package/dist/esm/signal/crypto/WaAdvSignature.js +60 -0
  158. package/dist/esm/signal/crypto/constants.js +8 -0
  159. package/dist/esm/signal/group/SenderKeyChain.js +97 -0
  160. package/dist/esm/signal/group/SenderKeyCodec.js +46 -0
  161. package/dist/esm/signal/group/SenderKeyManager.js +176 -0
  162. package/dist/esm/signal/index.js +11 -0
  163. package/dist/esm/signal/registration/keygen.js +31 -0
  164. package/dist/esm/signal/registration/utils.js +16 -0
  165. package/dist/esm/signal/session/SignalProtocol.js +122 -0
  166. package/dist/esm/signal/session/SignalRatchet.js +260 -0
  167. package/dist/esm/signal/session/SignalSerializer.js +63 -0
  168. package/dist/esm/signal/session/SignalSession.js +153 -0
  169. package/dist/esm/signal/store/sqlite.js +310 -0
  170. package/dist/esm/signal/types.js +1 -0
  171. package/dist/esm/store/contracts/appstate.store.js +1 -0
  172. package/dist/esm/store/contracts/auth.store.js +1 -0
  173. package/dist/esm/store/contracts/contact.store.js +1 -0
  174. package/dist/esm/store/contracts/device-list.store.js +1 -0
  175. package/dist/esm/store/contracts/message.store.js +1 -0
  176. package/dist/esm/store/contracts/participants.store.js +1 -0
  177. package/dist/esm/store/contracts/retry.store.js +1 -0
  178. package/dist/esm/store/contracts/sender-key.store.js +1 -0
  179. package/dist/esm/store/contracts/signal.store.js +1 -0
  180. package/dist/esm/store/contracts/thread.store.js +1 -0
  181. package/dist/esm/store/createStore.js +278 -0
  182. package/dist/esm/store/index.js +20 -0
  183. package/dist/esm/store/noop.store.js +43 -0
  184. package/dist/esm/store/providers/memory/appstate.store.js +101 -0
  185. package/dist/esm/store/providers/memory/contact.store.js +23 -0
  186. package/dist/esm/store/providers/memory/device-list.store.js +86 -0
  187. package/dist/esm/store/providers/memory/message.store.js +40 -0
  188. package/dist/esm/store/providers/memory/participants.store.js +61 -0
  189. package/dist/esm/store/providers/memory/retry.store.js +71 -0
  190. package/dist/esm/store/providers/memory/sender-key.store.js +88 -0
  191. package/dist/esm/store/providers/memory/signal.store.js +170 -0
  192. package/dist/esm/store/providers/memory/thread.store.js +34 -0
  193. package/dist/esm/store/providers/sqlite/BaseSqliteStore.js +37 -0
  194. package/dist/esm/store/providers/sqlite/appstate.store.js +169 -0
  195. package/dist/esm/store/providers/sqlite/auth.store.js +176 -0
  196. package/dist/esm/store/providers/sqlite/connection.js +240 -0
  197. package/dist/esm/store/providers/sqlite/contact.store.js +61 -0
  198. package/dist/esm/store/providers/sqlite/device-list.store.js +155 -0
  199. package/dist/esm/store/providers/sqlite/message.store.js +119 -0
  200. package/dist/esm/store/providers/sqlite/migrations.js +347 -0
  201. package/dist/esm/store/providers/sqlite/participants.store.js +85 -0
  202. package/dist/esm/store/providers/sqlite/retry.store.js +144 -0
  203. package/dist/esm/store/providers/sqlite/sender-key.store.js +203 -0
  204. package/dist/esm/store/providers/sqlite/signal.store.js +353 -0
  205. package/dist/esm/store/providers/sqlite/thread.store.js +72 -0
  206. package/dist/esm/store/types.js +1 -0
  207. package/dist/esm/transport/WaComms.js +527 -0
  208. package/dist/esm/transport/WaWebSocket.js +361 -0
  209. package/dist/esm/transport/binary/constants.js +96 -0
  210. package/dist/esm/transport/binary/decoder.js +275 -0
  211. package/dist/esm/transport/binary/encoder.js +210 -0
  212. package/dist/esm/transport/binary/index.js +4 -0
  213. package/dist/esm/transport/binary/tokens.js +1280 -0
  214. package/dist/esm/transport/index.js +6 -0
  215. package/dist/esm/transport/keepalive/WaKeepAlive.js +141 -0
  216. package/dist/esm/transport/node/WaNodeOrchestrator.js +143 -0
  217. package/dist/esm/transport/node/WaNodeTransport.js +64 -0
  218. package/dist/esm/transport/node/builders/accountSync.js +101 -0
  219. package/dist/esm/transport/node/builders/group.js +47 -0
  220. package/dist/esm/transport/node/builders/index.js +7 -0
  221. package/dist/esm/transport/node/builders/media.js +10 -0
  222. package/dist/esm/transport/node/builders/message.js +317 -0
  223. package/dist/esm/transport/node/builders/pairing.js +130 -0
  224. package/dist/esm/transport/node/builders/prekeys.js +102 -0
  225. package/dist/esm/transport/node/builders/retry.js +116 -0
  226. package/dist/esm/transport/node/helpers.js +37 -0
  227. package/dist/esm/transport/node/query.js +53 -0
  228. package/dist/esm/transport/node/xml.js +39 -0
  229. package/dist/esm/transport/noise/WaClientPayload.js +162 -0
  230. package/dist/esm/transport/noise/WaFrameCodec.js +121 -0
  231. package/dist/esm/transport/noise/WaNoiseCert.js +74 -0
  232. package/dist/esm/transport/noise/WaNoiseHandshake.js +57 -0
  233. package/dist/esm/transport/noise/WaNoiseSession.js +322 -0
  234. package/dist/esm/transport/noise/WaNoiseSocket.js +17 -0
  235. package/dist/esm/transport/noise/constants.js +8 -0
  236. package/dist/esm/transport/noise/types.js +1 -0
  237. package/dist/esm/transport/stream/parse.js +91 -0
  238. package/dist/esm/transport/types.js +1 -0
  239. package/dist/esm/util/async.js +5 -0
  240. package/dist/esm/util/base64.js +18 -0
  241. package/dist/esm/util/bytes.js +275 -0
  242. package/dist/esm/util/coercion.js +56 -0
  243. package/dist/esm/util/collections.js +27 -0
  244. package/dist/esm/util/primitives.js +32 -0
  245. package/dist/esm/util/runtime.js +15 -0
  246. package/dist/esm/util/signal-address.js +5 -0
  247. package/dist/index.js +52 -0
  248. package/dist/infra/log/ConsoleLogger.js +44 -0
  249. package/dist/infra/log/PinoLogger.js +111 -0
  250. package/dist/infra/log/types.js +2 -0
  251. package/dist/infra/perf/BoundedTaskQueue.js +67 -0
  252. package/dist/media/WaMediaCrypto.js +228 -0
  253. package/dist/media/WaMediaTransferClient.js +365 -0
  254. package/dist/media/conn.js +36 -0
  255. package/dist/media/constants.js +21 -0
  256. package/dist/media/index.js +9 -0
  257. package/dist/media/types.js +2 -0
  258. package/dist/message/WaMessageClient.js +214 -0
  259. package/dist/message/ack.js +52 -0
  260. package/dist/message/content.js +24 -0
  261. package/dist/message/device-sent.js +53 -0
  262. package/dist/message/incoming.js +321 -0
  263. package/dist/message/index.js +20 -0
  264. package/dist/message/padding.js +24 -0
  265. package/dist/message/phash.js +28 -0
  266. package/dist/message/types.js +2 -0
  267. package/dist/proto.js +5 -0
  268. package/dist/protocol/appstate.js +37 -0
  269. package/dist/protocol/auth.js +15 -0
  270. package/dist/protocol/browser.js +45 -0
  271. package/dist/protocol/constants.js +46 -0
  272. package/dist/protocol/defaults.js +30 -0
  273. package/dist/protocol/dirty.js +29 -0
  274. package/dist/protocol/group.js +8 -0
  275. package/dist/protocol/index.js +53 -0
  276. package/dist/protocol/jid.js +107 -0
  277. package/dist/protocol/media.js +24 -0
  278. package/dist/protocol/message.js +19 -0
  279. package/dist/protocol/nodes.js +86 -0
  280. package/dist/protocol/notification.js +53 -0
  281. package/dist/protocol/stream.js +63 -0
  282. package/dist/retry/constants.js +23 -0
  283. package/dist/retry/index.js +19 -0
  284. package/dist/retry/outbound.js +88 -0
  285. package/dist/retry/parse.js +133 -0
  286. package/dist/retry/reason.js +53 -0
  287. package/dist/retry/replay.js +181 -0
  288. package/dist/retry/types.js +2 -0
  289. package/dist/signal/api/SignalDeviceSyncApi.js +189 -0
  290. package/dist/signal/api/SignalDigestSyncApi.js +183 -0
  291. package/dist/signal/api/SignalIdentitySyncApi.js +115 -0
  292. package/dist/signal/api/SignalMissingPreKeysSyncApi.js +145 -0
  293. package/dist/signal/api/SignalRotateKeyApi.js +63 -0
  294. package/dist/signal/api/SignalSessionSyncApi.js +191 -0
  295. package/dist/signal/api/codec.js +27 -0
  296. package/dist/signal/api/constants.js +12 -0
  297. package/dist/signal/api/prekeys.js +16 -0
  298. package/dist/signal/constants.js +19 -0
  299. package/dist/signal/crypto/WaAdvSignature.js +72 -0
  300. package/dist/signal/crypto/constants.js +11 -0
  301. package/dist/signal/group/SenderKeyChain.js +101 -0
  302. package/dist/signal/group/SenderKeyCodec.js +50 -0
  303. package/dist/signal/group/SenderKeyManager.js +180 -0
  304. package/dist/signal/index.js +29 -0
  305. package/dist/signal/registration/keygen.js +37 -0
  306. package/dist/signal/registration/utils.js +19 -0
  307. package/dist/signal/session/SignalProtocol.js +126 -0
  308. package/dist/signal/session/SignalRatchet.js +268 -0
  309. package/dist/signal/session/SignalSerializer.js +69 -0
  310. package/dist/signal/session/SignalSession.js +165 -0
  311. package/dist/signal/store/sqlite.js +324 -0
  312. package/dist/signal/types.js +2 -0
  313. package/dist/store/contracts/appstate.store.js +2 -0
  314. package/dist/store/contracts/auth.store.js +2 -0
  315. package/dist/store/contracts/contact.store.js +2 -0
  316. package/dist/store/contracts/device-list.store.js +2 -0
  317. package/dist/store/contracts/message.store.js +2 -0
  318. package/dist/store/contracts/participants.store.js +2 -0
  319. package/dist/store/contracts/retry.store.js +2 -0
  320. package/dist/store/contracts/sender-key.store.js +2 -0
  321. package/dist/store/contracts/signal.store.js +2 -0
  322. package/dist/store/contracts/thread.store.js +2 -0
  323. package/dist/store/createStore.js +281 -0
  324. package/dist/store/index.js +43 -0
  325. package/dist/store/noop.store.js +46 -0
  326. package/dist/store/providers/memory/appstate.store.js +105 -0
  327. package/dist/store/providers/memory/contact.store.js +27 -0
  328. package/dist/store/providers/memory/device-list.store.js +90 -0
  329. package/dist/store/providers/memory/message.store.js +44 -0
  330. package/dist/store/providers/memory/participants.store.js +65 -0
  331. package/dist/store/providers/memory/retry.store.js +75 -0
  332. package/dist/store/providers/memory/sender-key.store.js +92 -0
  333. package/dist/store/providers/memory/signal.store.js +174 -0
  334. package/dist/store/providers/memory/thread.store.js +38 -0
  335. package/dist/store/providers/sqlite/BaseSqliteStore.js +41 -0
  336. package/dist/store/providers/sqlite/appstate.store.js +173 -0
  337. package/dist/store/providers/sqlite/auth.store.js +180 -0
  338. package/dist/store/providers/sqlite/connection.js +276 -0
  339. package/dist/store/providers/sqlite/contact.store.js +65 -0
  340. package/dist/store/providers/sqlite/device-list.store.js +159 -0
  341. package/dist/store/providers/sqlite/message.store.js +123 -0
  342. package/dist/store/providers/sqlite/migrations.js +350 -0
  343. package/dist/store/providers/sqlite/participants.store.js +89 -0
  344. package/dist/store/providers/sqlite/retry.store.js +148 -0
  345. package/dist/store/providers/sqlite/sender-key.store.js +207 -0
  346. package/dist/store/providers/sqlite/signal.store.js +357 -0
  347. package/dist/store/providers/sqlite/thread.store.js +76 -0
  348. package/dist/store/types.js +2 -0
  349. package/dist/transport/WaComms.js +531 -0
  350. package/dist/transport/WaWebSocket.js +365 -0
  351. package/dist/transport/binary/constants.js +99 -0
  352. package/dist/transport/binary/decoder.js +279 -0
  353. package/dist/transport/binary/encoder.js +214 -0
  354. package/dist/transport/binary/index.js +23 -0
  355. package/dist/transport/binary/tokens.js +1283 -0
  356. package/dist/transport/index.js +18 -0
  357. package/dist/transport/keepalive/WaKeepAlive.js +145 -0
  358. package/dist/transport/node/WaNodeOrchestrator.js +147 -0
  359. package/dist/transport/node/WaNodeTransport.js +68 -0
  360. package/dist/transport/node/builders/accountSync.js +110 -0
  361. package/dist/transport/node/builders/group.js +52 -0
  362. package/dist/transport/node/builders/index.js +39 -0
  363. package/dist/transport/node/builders/media.js +13 -0
  364. package/dist/transport/node/builders/message.js +328 -0
  365. package/dist/transport/node/builders/pairing.js +137 -0
  366. package/dist/transport/node/builders/prekeys.js +107 -0
  367. package/dist/transport/node/builders/retry.js +119 -0
  368. package/dist/transport/node/helpers.js +46 -0
  369. package/dist/transport/node/query.js +59 -0
  370. package/dist/transport/node/xml.js +42 -0
  371. package/dist/transport/noise/WaClientPayload.js +166 -0
  372. package/dist/transport/noise/WaFrameCodec.js +125 -0
  373. package/dist/transport/noise/WaNoiseCert.js +77 -0
  374. package/dist/transport/noise/WaNoiseHandshake.js +61 -0
  375. package/dist/transport/noise/WaNoiseSession.js +326 -0
  376. package/dist/transport/noise/WaNoiseSocket.js +21 -0
  377. package/dist/transport/noise/constants.js +11 -0
  378. package/dist/transport/noise/types.js +2 -0
  379. package/dist/transport/stream/parse.js +97 -0
  380. package/dist/transport/types.js +2 -0
  381. package/dist/types/appstate/WaAppStateCrypto.d.ts +59 -0
  382. package/dist/types/appstate/WaAppStateSyncClient.d.ts +63 -0
  383. package/dist/types/appstate/WaAppStateSyncResponseParser.d.ts +12 -0
  384. package/dist/types/appstate/constants.d.ts +14 -0
  385. package/dist/types/appstate/index.d.ts +7 -0
  386. package/dist/types/appstate/store/sqlite.d.ts +21 -0
  387. package/dist/types/appstate/types.d.ts +66 -0
  388. package/dist/types/appstate/utils.d.ts +10 -0
  389. package/dist/types/auth/WaAuthClient.d.ts +61 -0
  390. package/dist/types/auth/flow/WaAuthCredentialsFlow.d.ts +14 -0
  391. package/dist/types/auth/index.d.ts +6 -0
  392. package/dist/types/auth/pairing/WaPairingCodeCrypto.d.ts +17 -0
  393. package/dist/types/auth/pairing/WaPairingFlow.d.ts +48 -0
  394. package/dist/types/auth/pairing/WaQrFlow.d.ts +23 -0
  395. package/dist/types/auth/pairing/constants.d.ts +2 -0
  396. package/dist/types/auth/types.d.ts +48 -0
  397. package/dist/types/client/WaClient.d.ts +97 -0
  398. package/dist/types/client/WaClientFactory.d.ts +83 -0
  399. package/dist/types/client/coordinators/WaGroupCoordinator.d.ts +48 -0
  400. package/dist/types/client/coordinators/WaIncomingNodeCoordinator.d.ts +60 -0
  401. package/dist/types/client/coordinators/WaMessageDispatchCoordinator.d.ts +90 -0
  402. package/dist/types/client/coordinators/WaPassiveTasksCoordinator.d.ts +43 -0
  403. package/dist/types/client/coordinators/WaRetryCoordinator.d.ts +61 -0
  404. package/dist/types/client/coordinators/WaStreamControlCoordinator.d.ts +17 -0
  405. package/dist/types/client/dirty.d.ts +17 -0
  406. package/dist/types/client/events/chat.d.ts +3 -0
  407. package/dist/types/client/events/group.d.ts +7 -0
  408. package/dist/types/client/history-sync.d.ts +17 -0
  409. package/dist/types/client/incoming.d.ts +35 -0
  410. package/dist/types/client/index.d.ts +2 -0
  411. package/dist/types/client/mailbox.d.ts +12 -0
  412. package/dist/types/client/messages.d.ts +17 -0
  413. package/dist/types/client/types.d.ts +235 -0
  414. package/dist/types/crypto/core/constants.d.ts +1 -0
  415. package/dist/types/crypto/core/encoding.d.ts +11 -0
  416. package/dist/types/crypto/core/hkdf.d.ts +8 -0
  417. package/dist/types/crypto/core/index.d.ts +11 -0
  418. package/dist/types/crypto/core/keys.d.ts +20 -0
  419. package/dist/types/crypto/core/nonce.d.ts +5 -0
  420. package/dist/types/crypto/core/primitives.d.ts +25 -0
  421. package/dist/types/crypto/core/random.d.ts +8 -0
  422. package/dist/types/crypto/curves/Ed25519.d.ts +7 -0
  423. package/dist/types/crypto/curves/X25519.d.ts +8 -0
  424. package/dist/types/crypto/curves/constants.d.ts +2 -0
  425. package/dist/types/crypto/curves/types.d.ts +10 -0
  426. package/dist/types/crypto/index.d.ts +3 -0
  427. package/dist/types/crypto/math/constants.d.ts +7 -0
  428. package/dist/types/crypto/math/edwards.d.ts +3 -0
  429. package/dist/types/crypto/math/le.d.ts +2 -0
  430. package/dist/types/crypto/math/mod.d.ts +5 -0
  431. package/dist/types/crypto/math/types.d.ts +6 -0
  432. package/dist/types/index.d.ts +10 -0
  433. package/dist/types/infra/log/ConsoleLogger.d.ts +11 -0
  434. package/dist/types/infra/log/PinoLogger.d.ts +30 -0
  435. package/dist/types/infra/log/types.d.ts +9 -0
  436. package/dist/types/infra/perf/BoundedTaskQueue.d.ts +19 -0
  437. package/dist/types/media/WaMediaCrypto.d.ts +12 -0
  438. package/dist/types/media/WaMediaTransferClient.d.ts +81 -0
  439. package/dist/types/media/conn.d.ts +3 -0
  440. package/dist/types/media/constants.d.ts +10 -0
  441. package/dist/types/media/index.d.ts +4 -0
  442. package/dist/types/media/types.d.ts +56 -0
  443. package/dist/types/message/WaMessageClient.d.ts +29 -0
  444. package/dist/types/message/ack.d.ts +5 -0
  445. package/dist/types/message/content.d.ts +4 -0
  446. package/dist/types/message/device-sent.d.ts +3 -0
  447. package/dist/types/message/incoming.d.ts +18 -0
  448. package/dist/types/message/index.d.ts +2 -0
  449. package/dist/types/message/padding.d.ts +2 -0
  450. package/dist/types/message/phash.d.ts +1 -0
  451. package/dist/types/message/types.d.ts +58 -0
  452. package/dist/types/proto.d.ts +2 -0
  453. package/dist/types/protocol/appstate.d.ts +34 -0
  454. package/dist/types/protocol/auth.d.ts +12 -0
  455. package/dist/types/protocol/browser.d.ts +22 -0
  456. package/dist/types/protocol/constants.d.ts +11 -0
  457. package/dist/types/protocol/defaults.d.ts +26 -0
  458. package/dist/types/protocol/dirty.d.ts +15 -0
  459. package/dist/types/protocol/group.d.ts +6 -0
  460. package/dist/types/protocol/index.d.ts +11 -0
  461. package/dist/types/protocol/jid.d.ts +19 -0
  462. package/dist/types/protocol/media.d.ts +15 -0
  463. package/dist/types/protocol/message.d.ts +16 -0
  464. package/dist/types/protocol/nodes.d.ts +83 -0
  465. package/dist/types/protocol/notification.d.ts +50 -0
  466. package/dist/types/protocol/stream.d.ts +60 -0
  467. package/dist/types/retry/constants.d.ts +21 -0
  468. package/dist/types/retry/index.d.ts +7 -0
  469. package/dist/types/retry/outbound.d.ts +4 -0
  470. package/dist/types/retry/parse.d.ts +3 -0
  471. package/dist/types/retry/reason.d.ts +2 -0
  472. package/dist/types/retry/replay.d.ts +30 -0
  473. package/dist/types/retry/types.d.ts +70 -0
  474. package/dist/types/signal/api/SignalDeviceSyncApi.d.ts +31 -0
  475. package/dist/types/signal/api/SignalDigestSyncApi.d.ts +27 -0
  476. package/dist/types/signal/api/SignalIdentitySyncApi.d.ts +26 -0
  477. package/dist/types/signal/api/SignalMissingPreKeysSyncApi.d.ts +39 -0
  478. package/dist/types/signal/api/SignalRotateKeyApi.d.ts +22 -0
  479. package/dist/types/signal/api/SignalSessionSyncApi.d.ts +38 -0
  480. package/dist/types/signal/api/codec.d.ts +3 -0
  481. package/dist/types/signal/api/constants.d.ts +9 -0
  482. package/dist/types/signal/api/prekeys.d.ts +6 -0
  483. package/dist/types/signal/constants.d.ts +14 -0
  484. package/dist/types/signal/crypto/WaAdvSignature.d.ts +7 -0
  485. package/dist/types/signal/crypto/constants.d.ts +5 -0
  486. package/dist/types/signal/group/SenderKeyChain.d.ts +11 -0
  487. package/dist/types/signal/group/SenderKeyCodec.d.ts +14 -0
  488. package/dist/types/signal/group/SenderKeyManager.d.ts +22 -0
  489. package/dist/types/signal/index.d.ts +12 -0
  490. package/dist/types/signal/registration/keygen.d.ts +5 -0
  491. package/dist/types/signal/registration/utils.d.ts +9 -0
  492. package/dist/types/signal/session/SignalProtocol.d.ts +22 -0
  493. package/dist/types/signal/session/SignalRatchet.d.ts +25 -0
  494. package/dist/types/signal/session/SignalSerializer.d.ts +6 -0
  495. package/dist/types/signal/session/SignalSession.d.ts +43 -0
  496. package/dist/types/signal/store/sqlite.d.ts +72 -0
  497. package/dist/types/signal/types.d.ts +110 -0
  498. package/dist/types/store/contracts/appstate.store.d.ts +22 -0
  499. package/dist/types/store/contracts/auth.store.d.ts +6 -0
  500. package/dist/types/store/contracts/contact.store.d.ts +14 -0
  501. package/dist/types/store/contracts/device-list.store.d.ts +16 -0
  502. package/dist/types/store/contracts/message.store.d.ts +18 -0
  503. package/dist/types/store/contracts/participants.store.d.ts +14 -0
  504. package/dist/types/store/contracts/retry.store.d.ts +11 -0
  505. package/dist/types/store/contracts/sender-key.store.d.ts +16 -0
  506. package/dist/types/store/contracts/signal.store.d.ts +31 -0
  507. package/dist/types/store/contracts/thread.store.d.ts +17 -0
  508. package/dist/types/store/createStore.d.ts +2 -0
  509. package/dist/types/store/index.d.ts +31 -0
  510. package/dist/types/store/noop.store.d.ts +10 -0
  511. package/dist/types/store/providers/memory/appstate.store.d.ts +21 -0
  512. package/dist/types/store/providers/memory/contact.store.d.ts +13 -0
  513. package/dist/types/store/providers/memory/device-list.store.d.ts +20 -0
  514. package/dist/types/store/providers/memory/message.store.d.ts +14 -0
  515. package/dist/types/store/providers/memory/participants.store.d.ts +18 -0
  516. package/dist/types/store/providers/memory/retry.store.d.ts +18 -0
  517. package/dist/types/store/providers/memory/sender-key.store.d.ts +28 -0
  518. package/dist/types/store/providers/memory/signal.store.d.ts +51 -0
  519. package/dist/types/store/providers/memory/thread.store.d.ts +14 -0
  520. package/dist/types/store/providers/sqlite/BaseSqliteStore.d.ts +12 -0
  521. package/dist/types/store/providers/sqlite/appstate.store.d.ts +15 -0
  522. package/dist/types/store/providers/sqlite/auth.store.d.ts +10 -0
  523. package/dist/types/store/providers/sqlite/connection.d.ts +10 -0
  524. package/dist/types/store/providers/sqlite/contact.store.d.ts +10 -0
  525. package/dist/types/store/providers/sqlite/device-list.store.d.ts +18 -0
  526. package/dist/types/store/providers/sqlite/message.store.d.ts +11 -0
  527. package/dist/types/store/providers/sqlite/migrations.d.ts +3 -0
  528. package/dist/types/store/providers/sqlite/participants.store.d.ts +13 -0
  529. package/dist/types/store/providers/sqlite/retry.store.d.ts +16 -0
  530. package/dist/types/store/providers/sqlite/sender-key.store.d.ts +25 -0
  531. package/dist/types/store/providers/sqlite/signal.store.d.ts +46 -0
  532. package/dist/types/store/providers/sqlite/thread.store.d.ts +11 -0
  533. package/dist/types/store/types.d.ts +103 -0
  534. package/dist/types/transport/WaComms.d.ts +61 -0
  535. package/dist/types/transport/WaWebSocket.d.ts +36 -0
  536. package/dist/types/transport/binary/constants.d.ts +49 -0
  537. package/dist/types/transport/binary/decoder.d.ts +3 -0
  538. package/dist/types/transport/binary/encoder.d.ts +3 -0
  539. package/dist/types/transport/binary/index.d.ts +4 -0
  540. package/dist/types/transport/binary/tokens.d.ts +11 -0
  541. package/dist/types/transport/index.d.ts +7 -0
  542. package/dist/types/transport/keepalive/WaKeepAlive.d.ts +39 -0
  543. package/dist/types/transport/node/WaNodeOrchestrator.d.ts +28 -0
  544. package/dist/types/transport/node/WaNodeTransport.d.ts +22 -0
  545. package/dist/types/transport/node/builders/accountSync.d.ts +11 -0
  546. package/dist/types/transport/node/builders/group.d.ts +16 -0
  547. package/dist/types/transport/node/builders/index.d.ts +7 -0
  548. package/dist/types/transport/node/builders/media.d.ts +2 -0
  549. package/dist/types/transport/node/builders/message.d.ts +52 -0
  550. package/dist/types/transport/node/builders/pairing.d.ts +18 -0
  551. package/dist/types/transport/node/builders/prekeys.d.ts +5 -0
  552. package/dist/types/transport/node/builders/retry.d.ts +18 -0
  553. package/dist/types/transport/node/helpers.d.ts +8 -0
  554. package/dist/types/transport/node/query.d.ts +10 -0
  555. package/dist/types/transport/node/xml.d.ts +2 -0
  556. package/dist/types/transport/noise/WaClientPayload.d.ts +3 -0
  557. package/dist/types/transport/noise/WaFrameCodec.d.ts +9 -0
  558. package/dist/types/transport/noise/WaNoiseCert.d.ts +1 -0
  559. package/dist/types/transport/noise/WaNoiseHandshake.d.ts +14 -0
  560. package/dist/types/transport/noise/WaNoiseSession.d.ts +33 -0
  561. package/dist/types/transport/noise/WaNoiseSocket.d.ts +10 -0
  562. package/dist/types/transport/noise/constants.d.ts +7 -0
  563. package/dist/types/transport/noise/types.d.ts +23 -0
  564. package/dist/types/transport/stream/parse.d.ts +23 -0
  565. package/dist/types/transport/types.d.ts +71 -0
  566. package/dist/types/util/async.d.ts +1 -0
  567. package/dist/types/util/base64.d.ts +4 -0
  568. package/dist/types/util/bytes.d.ts +28 -0
  569. package/dist/types/util/coercion.d.ts +8 -0
  570. package/dist/types/util/collections.d.ts +3 -0
  571. package/dist/types/util/primitives.d.ts +7 -0
  572. package/dist/types/util/runtime.d.ts +2 -0
  573. package/dist/types/util/signal-address.d.ts +2 -0
  574. package/dist/util/async.js +8 -0
  575. package/dist/util/base64.js +24 -0
  576. package/dist/util/bytes.js +291 -0
  577. package/dist/util/coercion.js +66 -0
  578. package/dist/util/collections.js +32 -0
  579. package/dist/util/primitives.js +37 -0
  580. package/dist/util/runtime.js +19 -0
  581. package/dist/util/signal-address.js +8 -0
  582. package/package.json +150 -0
  583. package/proto/index.d.ts +10861 -0
  584. package/proto/index.js +1 -0
  585. package/scripts/check-node-version.cjs +55 -0
@@ -0,0 +1,745 @@
1
+ import { EventEmitter } from 'node:events';
2
+ import { downloadExternalBlobReference } from '../appstate/utils.js';
3
+ import { parseChatEventFromAppStateMutation } from './events/chat.js';
4
+ import { processHistorySyncNotification } from './history-sync.js';
5
+ import { persistIncomingMailboxEntities } from './mailbox.js';
6
+ import { buildWaClientDependencies, resolveWaClientBase } from './WaClientFactory.js';
7
+ import { ConsoleLogger } from '../infra/log/ConsoleLogger.js';
8
+ import { proto } from '../proto.js';
9
+ import { WA_APP_STATE_COLLECTION_STATES, WA_DEFAULTS, WA_MESSAGE_TAGS } from '../protocol/constants.js';
10
+ import { normalizeDeviceJid, toUserJid } from '../protocol/jid.js';
11
+ import { queryWithContext as queryNodeWithContext } from '../transport/node/query.js';
12
+ import { WaComms } from '../transport/WaComms.js';
13
+ import { decodeProtoBytes } from '../util/base64.js';
14
+ import { bytesToHex } from '../util/bytes.js';
15
+ import { toError } from '../util/primitives.js';
16
+ const SYNC_RELATED_PROTOCOL_TYPES = new Set([
17
+ proto.Message.ProtocolMessage.Type.APP_STATE_SYNC_KEY_REQUEST,
18
+ proto.Message.ProtocolMessage.Type.APP_STATE_FATAL_EXCEPTION_NOTIFICATION,
19
+ proto.Message.ProtocolMessage.Type.PEER_DATA_OPERATION_REQUEST_MESSAGE,
20
+ proto.Message.ProtocolMessage.Type.PEER_DATA_OPERATION_REQUEST_RESPONSE_MESSAGE
21
+ ]);
22
+ const WA_APP_STATE_KEY_SHARE_WAIT_TIMEOUT_MS = 15000;
23
+ const WA_APP_STATE_KEY_SHARE_MAX_RETRIES = 2;
24
+ export class WaClient extends EventEmitter {
25
+ constructor(options, logger = new ConsoleLogger('info')) {
26
+ super();
27
+ this.clockSkewMs = null;
28
+ this.mediaConnCache = null;
29
+ this.comms = null;
30
+ this.pairingReconnectPromise = null;
31
+ this.connectPromise = null;
32
+ this.danglingReceipts = [];
33
+ this.appStateKeyShareWaiters = new Set();
34
+ this.appStateKeyShareVersion = 0;
35
+ this.appStateBootstrapKeyShareWaitDone = false;
36
+ const base = resolveWaClientBase(options, logger);
37
+ this.options = base.options;
38
+ this.logger = base.logger;
39
+ this.appStateStore = base.sessionStore.appState;
40
+ this.contactStore = base.sessionStore.contacts;
41
+ this.messageStore = base.sessionStore.messages;
42
+ this.participantsStore = base.sessionStore.participants;
43
+ this.deviceListStore = base.sessionStore.deviceList;
44
+ this.retryStore = base.sessionStore.retry;
45
+ this.signalStore = base.sessionStore.signal;
46
+ this.senderKeyStore = base.sessionStore.senderKey;
47
+ this.threadStore = base.sessionStore.threads;
48
+ const host = {
49
+ sendNode: (node) => this.sendNode(node),
50
+ query: (node, timeoutMs) => this.query(node, timeoutMs),
51
+ queryWithContext: this.queryWithContext.bind(this),
52
+ syncAppState: () => this.syncAppState().then(() => { }),
53
+ emitEvent: this.emit.bind(this),
54
+ handleIncomingMessageEvent: this.handleIncomingMessageEvent.bind(this),
55
+ handleError: this.handleError.bind(this),
56
+ scheduleReconnectAfterPairing: this.scheduleReconnectAfterPairing.bind(this),
57
+ updateClockSkewFromSuccess: this.updateClockSkewFromSuccess.bind(this),
58
+ getComms: () => this.comms,
59
+ getMediaConnCache: () => this.mediaConnCache,
60
+ setMediaConnCache: (mediaConn) => {
61
+ this.mediaConnCache = mediaConn;
62
+ },
63
+ disconnect: this.disconnect.bind(this),
64
+ clearStoredState: this.clearStoredState.bind(this),
65
+ connect: this.connect.bind(this),
66
+ shouldQueueDanglingReceipt: (node, error) => this.shouldQueueDanglingReceipt(node, error),
67
+ enqueueDanglingReceipt: this.enqueueDanglingReceipt.bind(this),
68
+ takeDanglingReceipts: () => this.danglingReceipts.splice(0)
69
+ };
70
+ const dependencies = buildWaClientDependencies({
71
+ base,
72
+ host
73
+ });
74
+ Object.assign(this, dependencies);
75
+ this.bindNodeTransportEvents();
76
+ }
77
+ on(event, listener) {
78
+ return super.on(event, listener);
79
+ }
80
+ once(event, listener) {
81
+ return super.once(event, listener);
82
+ }
83
+ off(event, listener) {
84
+ return super.off(event, listener);
85
+ }
86
+ emit(event, ...args) {
87
+ return super.emit(event, ...args);
88
+ }
89
+ getState() {
90
+ const connected = this.comms !== null && this.comms.getCommsState().connected;
91
+ this.logger.trace('wa client state requested', { connected });
92
+ return this.authClient.getState(connected);
93
+ }
94
+ getCredentials() {
95
+ return this.authClient.getCurrentCredentials();
96
+ }
97
+ getClockSkewMs() {
98
+ return this.clockSkewMs;
99
+ }
100
+ async sendNode(node) {
101
+ try {
102
+ await this.nodeOrchestrator.sendNode(node);
103
+ }
104
+ catch (error) {
105
+ const normalized = toError(error);
106
+ if (this.shouldQueueDanglingReceipt(node, normalized)) {
107
+ this.enqueueDanglingReceipt(node);
108
+ this.logger.warn('queued dangling receipt after send failure', {
109
+ id: node.attrs.id,
110
+ to: node.attrs.to,
111
+ message: normalized.message,
112
+ queueSize: this.danglingReceipts.length
113
+ });
114
+ return;
115
+ }
116
+ throw normalized;
117
+ }
118
+ }
119
+ async query(node, timeoutMs = this.options.iqTimeoutMs ?? WA_DEFAULTS.IQ_TIMEOUT_MS) {
120
+ if (!this.comms || !this.comms.getCommsState().connected) {
121
+ throw new Error('client is not connected');
122
+ }
123
+ this.logger.debug('wa client query', { tag: node.tag, id: node.attrs.id, timeoutMs });
124
+ return this.nodeOrchestrator.query(node, timeoutMs);
125
+ }
126
+ registerIncomingHandler(registration) {
127
+ return this.incomingNode.registerIncomingHandler(registration);
128
+ }
129
+ unregisterIncomingHandler(registration) {
130
+ return this.incomingNode.unregisterIncomingHandler(registration);
131
+ }
132
+ bindNodeTransportEvents() {
133
+ this.nodeTransport.on('frame_in', (frame) => this.emit('transport_frame_in', { frame }));
134
+ this.nodeTransport.on('frame_out', (frame) => this.emit('transport_frame_out', { frame }));
135
+ this.nodeTransport.on('node_in', (node, frame) => this.emit('transport_node_in', { node, frame }));
136
+ this.nodeTransport.on('node_out', (node, frame) => this.emit('transport_node_out', { node, frame }));
137
+ this.nodeTransport.on('decode_error', (error, frame) => {
138
+ this.emit('transport_decode_error', { error, frame });
139
+ this.handleError(error);
140
+ });
141
+ }
142
+ async handleIncomingMessageEvent(event) {
143
+ this.emit('message', event);
144
+ void persistIncomingMailboxEntities({
145
+ logger: this.logger,
146
+ contactStore: this.contactStore,
147
+ messageStore: this.messageStore,
148
+ event
149
+ });
150
+ const protocolMessage = event.message?.protocolMessage;
151
+ if (!protocolMessage) {
152
+ return;
153
+ }
154
+ const protocolEvent = {
155
+ ...event,
156
+ protocolMessage
157
+ };
158
+ this.emit('message_protocol', protocolEvent);
159
+ const protocolType = protocolMessage.type;
160
+ if (protocolType === null || protocolType === undefined) {
161
+ this.logger.debug('incoming protocol message without type', {
162
+ id: event.stanzaId,
163
+ from: event.chatJid
164
+ });
165
+ return;
166
+ }
167
+ if (protocolType === proto.Message.ProtocolMessage.Type.APP_STATE_SYNC_KEY_REQUEST) {
168
+ await this.handleIncomingAppStateSyncKeyRequest(event, protocolMessage);
169
+ return;
170
+ }
171
+ if (protocolType === proto.Message.ProtocolMessage.Type.APP_STATE_SYNC_KEY_SHARE) {
172
+ await this.handleIncomingAppStateSyncKeyShare(event, protocolMessage);
173
+ return;
174
+ }
175
+ if (protocolType === proto.Message.ProtocolMessage.Type.HISTORY_SYNC_NOTIFICATION) {
176
+ if (this.options.history?.enabled && protocolMessage.historySyncNotification) {
177
+ await this.handleHistorySyncNotification(protocolMessage.historySyncNotification);
178
+ }
179
+ return;
180
+ }
181
+ if (SYNC_RELATED_PROTOCOL_TYPES.has(protocolType)) {
182
+ this.logger.info('incoming sync-related protocol message', {
183
+ id: event.stanzaId,
184
+ from: event.chatJid,
185
+ protocolType
186
+ });
187
+ return;
188
+ }
189
+ this.logger.debug('incoming protocol message received', {
190
+ id: event.stanzaId,
191
+ from: event.chatJid,
192
+ protocolType
193
+ });
194
+ }
195
+ async handleIncomingAppStateSyncKeyShare(event, protocolMessage) {
196
+ const share = protocolMessage.appStateSyncKeyShare;
197
+ if (!share) {
198
+ this.logger.warn('incoming app-state key share protocol message without payload', {
199
+ id: event.stanzaId,
200
+ from: event.chatJid
201
+ });
202
+ return;
203
+ }
204
+ try {
205
+ const imported = await this.appStateSync.importSyncKeyShare(share);
206
+ this.logger.info('imported app-state sync key share from protocol message', {
207
+ id: event.stanzaId,
208
+ from: event.chatJid,
209
+ imported
210
+ });
211
+ if (imported > 0) {
212
+ const hadWaiters = this.appStateKeyShareWaiters.size > 0;
213
+ this.appStateKeyShareVersion += 1;
214
+ this.notifyAppStateKeyShareWaiters(true);
215
+ if (hadWaiters) {
216
+ this.logger.debug('app-state key share imported and waiters released', {
217
+ id: event.stanzaId,
218
+ from: event.chatJid,
219
+ imported
220
+ });
221
+ return;
222
+ }
223
+ void this.syncAppState().catch((error) => {
224
+ this.logger.warn('failed to sync app-state after key share import', {
225
+ id: event.stanzaId,
226
+ from: event.chatJid,
227
+ message: toError(error).message
228
+ });
229
+ });
230
+ }
231
+ }
232
+ catch (error) {
233
+ this.logger.warn('failed to import app-state sync key share from protocol message', {
234
+ id: event.stanzaId,
235
+ from: event.chatJid,
236
+ message: toError(error).message
237
+ });
238
+ }
239
+ }
240
+ async handleIncomingAppStateSyncKeyRequest(event, protocolMessage) {
241
+ const request = protocolMessage.appStateSyncKeyRequest;
242
+ if (!request) {
243
+ this.logger.warn('incoming app-state key request protocol message without payload', {
244
+ id: event.stanzaId,
245
+ from: event.chatJid
246
+ });
247
+ return;
248
+ }
249
+ const requesterRaw = event.senderJid ?? event.chatJid;
250
+ if (!requesterRaw) {
251
+ this.logger.warn('incoming app-state key request missing sender jid', {
252
+ id: event.stanzaId
253
+ });
254
+ return;
255
+ }
256
+ let requesterDeviceJid;
257
+ try {
258
+ requesterDeviceJid = normalizeDeviceJid(requesterRaw);
259
+ }
260
+ catch (error) {
261
+ this.logger.warn('incoming app-state key request has malformed sender jid', {
262
+ id: event.stanzaId,
263
+ from: requesterRaw,
264
+ message: toError(error).message
265
+ });
266
+ return;
267
+ }
268
+ if (!this.isOwnAccountDeviceJid(requesterDeviceJid)) {
269
+ this.logger.warn('incoming app-state key request ignored: sender is not own account', {
270
+ id: event.stanzaId,
271
+ from: requesterDeviceJid
272
+ });
273
+ return;
274
+ }
275
+ const requestedKeyIds = this.extractAppStateSyncKeyRequestIds(request);
276
+ if (requestedKeyIds.length === 0) {
277
+ this.logger.warn('incoming app-state key request has no valid key ids', {
278
+ id: event.stanzaId,
279
+ from: requesterDeviceJid
280
+ });
281
+ return;
282
+ }
283
+ const requestedKeys = await Promise.all(requestedKeyIds.map((keyId) => this.appStateStore.getSyncKey(keyId)));
284
+ const availableKeys = requestedKeys.filter((key) => key !== null);
285
+ const missingKeyIds = requestedKeyIds.filter((_, index) => requestedKeys[index] === null);
286
+ try {
287
+ await this.messageDispatch.sendAppStateSyncKeyShare(requesterDeviceJid, availableKeys, missingKeyIds);
288
+ this.logger.info('responded to app-state key request', {
289
+ id: event.stanzaId,
290
+ to: requesterDeviceJid,
291
+ requested: requestedKeyIds.length,
292
+ shared: availableKeys.length,
293
+ missing: missingKeyIds.length
294
+ });
295
+ }
296
+ catch (error) {
297
+ this.logger.warn('failed to respond to app-state key request', {
298
+ id: event.stanzaId,
299
+ to: requesterDeviceJid,
300
+ requested: requestedKeyIds.length,
301
+ shared: availableKeys.length,
302
+ missing: missingKeyIds.length,
303
+ message: toError(error).message
304
+ });
305
+ }
306
+ }
307
+ extractAppStateSyncKeyRequestIds(request) {
308
+ const deduped = new Map();
309
+ for (const key of request.keyIds ?? []) {
310
+ try {
311
+ const keyId = decodeProtoBytes(key.keyId, 'appStateSyncKeyRequest.keyIds[].keyId');
312
+ const keyHex = bytesToHex(keyId);
313
+ if (deduped.has(keyHex)) {
314
+ continue;
315
+ }
316
+ deduped.set(keyHex, keyId);
317
+ }
318
+ catch (error) {
319
+ this.logger.trace('ignoring malformed app-state key id request entry', {
320
+ message: toError(error).message
321
+ });
322
+ }
323
+ }
324
+ return [...deduped.values()];
325
+ }
326
+ isOwnAccountDeviceJid(candidateJid) {
327
+ const credentials = this.authClient.getCurrentCredentials();
328
+ if (!credentials) {
329
+ return false;
330
+ }
331
+ const candidateUser = toUserJid(candidateJid);
332
+ const meUsers = [credentials.meJid, credentials.meLid]
333
+ .filter((value) => !!value)
334
+ .map((jid) => toUserJid(jid));
335
+ return meUsers.includes(candidateUser);
336
+ }
337
+ async handleHistorySyncNotification(notification) {
338
+ try {
339
+ await processHistorySyncNotification({
340
+ logger: this.logger,
341
+ mediaTransfer: this.mediaTransfer,
342
+ contactStore: this.contactStore,
343
+ messageStore: this.messageStore,
344
+ threadStore: this.threadStore,
345
+ emitEvent: this.emit.bind(this)
346
+ }, notification);
347
+ }
348
+ catch (error) {
349
+ this.logger.warn('failed to process history sync notification', {
350
+ syncType: notification.syncType,
351
+ chunkOrder: notification.chunkOrder,
352
+ message: toError(error).message
353
+ });
354
+ }
355
+ }
356
+ async queryWithContext(context, node, timeoutMs = this.options.iqTimeoutMs ?? WA_DEFAULTS.IQ_TIMEOUT_MS, contextData = {}) {
357
+ return queryNodeWithContext(async (queryNode, queryTimeoutMs) => this.query(queryNode, queryTimeoutMs), this.logger, context, node, timeoutMs, contextData);
358
+ }
359
+ async handleIncomingFrame(frame) {
360
+ try {
361
+ await this.nodeTransport.dispatchIncomingFrame(frame, async (node) => this.incomingNode.handleIncomingNode(node));
362
+ }
363
+ catch (error) {
364
+ this.handleError(toError(error));
365
+ }
366
+ }
367
+ async connect() {
368
+ if (this.connectPromise) {
369
+ this.logger.trace('wa client connect already in-flight');
370
+ return this.connectPromise;
371
+ }
372
+ this.connectPromise = this.connectInternal().finally(() => {
373
+ this.connectPromise = null;
374
+ });
375
+ return this.connectPromise;
376
+ }
377
+ async connectInternal() {
378
+ if (this.comms) {
379
+ this.logger.trace('wa client connect skipped: comms already created');
380
+ return;
381
+ }
382
+ this.logger.info('wa client connect start');
383
+ let credentials = await this.authClient.loadOrCreateCredentials();
384
+ try {
385
+ await this.startCommsWithCredentials(credentials);
386
+ }
387
+ catch (error) {
388
+ if (credentials.routingInfo) {
389
+ this.logger.warn('connect failed with routing info, retrying without routing info', {
390
+ message: toError(error).message
391
+ });
392
+ await this.disconnect();
393
+ credentials = await this.authClient.clearRoutingInfo();
394
+ await this.startCommsWithCredentials(credentials);
395
+ }
396
+ else {
397
+ await this.disconnect();
398
+ throw error;
399
+ }
400
+ }
401
+ this.logger.info('wa client connected');
402
+ this.emit('connection_open', {});
403
+ }
404
+ scheduleReconnectAfterPairing() {
405
+ this.logger.debug('wa client scheduling reconnect after pairing');
406
+ setTimeout(() => {
407
+ void this.reconnectAsRegisteredAfterPairing().catch((error) => {
408
+ this.handleError(toError(error));
409
+ });
410
+ }, 0);
411
+ }
412
+ async reconnectAsRegisteredAfterPairing() {
413
+ if (this.pairingReconnectPromise) {
414
+ this.logger.trace('pairing reconnect already in-flight');
415
+ return this.pairingReconnectPromise;
416
+ }
417
+ this.pairingReconnectPromise = this.reconnectAsRegisteredAfterPairingInternal().finally(() => {
418
+ this.pairingReconnectPromise = null;
419
+ });
420
+ return this.pairingReconnectPromise;
421
+ }
422
+ async reconnectAsRegisteredAfterPairingInternal() {
423
+ const credentials = this.authClient.getCurrentCredentials();
424
+ if (!credentials?.meJid) {
425
+ this.logger.trace('pairing reconnect skipped: still unregistered');
426
+ return;
427
+ }
428
+ const currentComms = this.comms;
429
+ if (!currentComms) {
430
+ this.logger.trace('pairing reconnect skipped: no active comms');
431
+ return;
432
+ }
433
+ this.logger.info('pairing completed, restarting comms as registered');
434
+ this.keepAlive.stop();
435
+ this.nodeOrchestrator.clearPending(new Error('restarting comms after pairing'));
436
+ this.clearCommsBinding();
437
+ try {
438
+ await currentComms.stopComms();
439
+ }
440
+ catch (error) {
441
+ this.logger.warn('failed to stop pre-registration comms', {
442
+ message: toError(error).message
443
+ });
444
+ }
445
+ try {
446
+ await this.startCommsWithCredentials(credentials);
447
+ }
448
+ catch (error) {
449
+ this.logger.warn('pairing reconnect failed while starting registered comms', {
450
+ message: toError(error).message
451
+ });
452
+ throw error;
453
+ }
454
+ }
455
+ async disconnect() {
456
+ this.logger.info('wa client disconnect start');
457
+ this.keepAlive.stop();
458
+ this.notifyAppStateKeyShareWaiters(false);
459
+ this.appStateBootstrapKeyShareWaitDone = false;
460
+ await this.authClient.clearTransientState();
461
+ this.nodeOrchestrator.clearPending(new Error('client disconnected'));
462
+ this.clockSkewMs = null;
463
+ this.mediaConnCache = null;
464
+ this.passiveTasks.resetInFlightState();
465
+ const comms = this.comms;
466
+ this.clearCommsBinding();
467
+ if (comms) {
468
+ await comms.stopComms();
469
+ this.logger.info('wa client disconnected');
470
+ this.emit('connection_close', {});
471
+ }
472
+ }
473
+ async requestPairingCode(phoneNumber, shouldShowPushNotification = false) {
474
+ if (!this.comms || !this.authClient.getCurrentCredentials()) {
475
+ throw new Error('client is not connected');
476
+ }
477
+ this.logger.debug('wa client request pairing code');
478
+ return this.authClient.requestPairingCode(phoneNumber, shouldShowPushNotification);
479
+ }
480
+ async fetchPairingCountryCodeIso() {
481
+ if (!this.comms || !this.authClient.getCurrentCredentials()) {
482
+ throw new Error('client is not connected');
483
+ }
484
+ this.logger.trace('wa client fetch pairing country code iso');
485
+ return this.authClient.fetchPairingCountryCodeIso();
486
+ }
487
+ async sendMessage(to, content, options = {}) {
488
+ return this.messageDispatch.sendMessage(to, content, options);
489
+ }
490
+ async syncSignalSession(jid, reasonIdentity = false) {
491
+ await this.messageDispatch.syncSignalSession(jid, reasonIdentity);
492
+ }
493
+ async sendReceipt(input) {
494
+ await this.messageDispatch.sendReceipt(input);
495
+ }
496
+ async exportAppState() {
497
+ return this.appStateSync.exportState();
498
+ }
499
+ async syncAppState(options = {}) {
500
+ if (!this.comms) {
501
+ throw new Error('client is not connected');
502
+ }
503
+ const shouldWaitForKeyShare = (await this.appStateStore.getActiveSyncKey()) === null;
504
+ if (shouldWaitForKeyShare && !this.appStateBootstrapKeyShareWaitDone) {
505
+ this.appStateBootstrapKeyShareWaitDone = true;
506
+ this.logger.info('app-state bootstrap pre-sync waiting for key share', {
507
+ timeoutMs: WA_APP_STATE_KEY_SHARE_WAIT_TIMEOUT_MS
508
+ });
509
+ const received = await this.waitForAppStateKeyShare(WA_APP_STATE_KEY_SHARE_WAIT_TIMEOUT_MS);
510
+ if (received) {
511
+ this.logger.info('app-state bootstrap pre-sync received key share, continuing sync');
512
+ }
513
+ else {
514
+ this.logger.warn('app-state bootstrap pre-sync key share wait timed out, continuing sync', {
515
+ timeoutMs: WA_APP_STATE_KEY_SHARE_WAIT_TIMEOUT_MS
516
+ });
517
+ }
518
+ }
519
+ let syncResult = await this.executeAppStateSync(options);
520
+ let blockedCollections = this.getBlockedAppStateCollections(syncResult);
521
+ if (!shouldWaitForKeyShare || blockedCollections.length === 0) {
522
+ this.emitChatEventsFromAppStateSyncResult(syncResult);
523
+ return syncResult;
524
+ }
525
+ let retryCount = 0;
526
+ let observedKeyShareVersion = this.appStateKeyShareVersion;
527
+ while (blockedCollections.length > 0 &&
528
+ retryCount < WA_APP_STATE_KEY_SHARE_MAX_RETRIES) {
529
+ const hasFreshShare = this.appStateKeyShareVersion !== observedKeyShareVersion;
530
+ if (!hasFreshShare) {
531
+ this.logger.info('app-state bootstrap waiting for key share', {
532
+ blockedCollections: blockedCollections.join(','),
533
+ timeoutMs: WA_APP_STATE_KEY_SHARE_WAIT_TIMEOUT_MS,
534
+ retryCount: retryCount + 1
535
+ });
536
+ const received = await this.waitForAppStateKeyShare(WA_APP_STATE_KEY_SHARE_WAIT_TIMEOUT_MS);
537
+ if (!received) {
538
+ this.logger.warn('app-state bootstrap key share wait timed out', {
539
+ blockedCollections: blockedCollections.join(','),
540
+ timeoutMs: WA_APP_STATE_KEY_SHARE_WAIT_TIMEOUT_MS
541
+ });
542
+ break;
543
+ }
544
+ }
545
+ observedKeyShareVersion = this.appStateKeyShareVersion;
546
+ retryCount += 1;
547
+ this.logger.info('app-state bootstrap retrying sync after key share', {
548
+ retryCount,
549
+ blockedCollections: blockedCollections.join(',')
550
+ });
551
+ syncResult = await this.executeAppStateSync(options);
552
+ blockedCollections = this.getBlockedAppStateCollections(syncResult);
553
+ }
554
+ if (blockedCollections.length > 0) {
555
+ this.logger.warn('app-state bootstrap still blocked after waiting for key share', {
556
+ blockedCollections: blockedCollections.join(','),
557
+ retries: retryCount
558
+ });
559
+ }
560
+ this.emitChatEventsFromAppStateSyncResult(syncResult);
561
+ return syncResult;
562
+ }
563
+ async executeAppStateSync(options) {
564
+ return options.downloadExternalBlob
565
+ ? this.appStateSync.sync(options)
566
+ : this.appStateSync.sync({
567
+ ...options,
568
+ downloadExternalBlob: async (_collection, _kind, reference) => downloadExternalBlobReference(this.mediaTransfer, reference)
569
+ });
570
+ }
571
+ getBlockedAppStateCollections(syncResult) {
572
+ return syncResult.collections
573
+ .filter((entry) => entry.state === WA_APP_STATE_COLLECTION_STATES.BLOCKED)
574
+ .map((entry) => entry.collection);
575
+ }
576
+ async waitForAppStateKeyShare(timeoutMs) {
577
+ return new Promise((resolve) => {
578
+ let settled = false;
579
+ let timeoutHandle = null;
580
+ const waiter = (received) => {
581
+ if (settled) {
582
+ return;
583
+ }
584
+ settled = true;
585
+ if (timeoutHandle) {
586
+ clearTimeout(timeoutHandle);
587
+ timeoutHandle = null;
588
+ }
589
+ this.appStateKeyShareWaiters.delete(waiter);
590
+ resolve(received);
591
+ };
592
+ this.appStateKeyShareWaiters.add(waiter);
593
+ timeoutHandle = setTimeout(() => {
594
+ waiter(false);
595
+ }, timeoutMs);
596
+ });
597
+ }
598
+ notifyAppStateKeyShareWaiters(received) {
599
+ if (this.appStateKeyShareWaiters.size === 0) {
600
+ return;
601
+ }
602
+ const waiters = [...this.appStateKeyShareWaiters.values()];
603
+ this.appStateKeyShareWaiters.clear();
604
+ for (const waiter of waiters) {
605
+ waiter(received);
606
+ }
607
+ }
608
+ emitChatEventsFromAppStateSyncResult(syncResult) {
609
+ const shouldEmitSnapshotMutations = this.options.chatEvents?.emitSnapshotMutations === true;
610
+ for (const collectionResult of syncResult.collections) {
611
+ const mutations = collectionResult.mutations ?? [];
612
+ const lastMutationIndexByKey = new Map();
613
+ for (let mutationIndex = 0; mutationIndex < mutations.length; mutationIndex += 1) {
614
+ const mutation = mutations[mutationIndex];
615
+ if (!shouldEmitSnapshotMutations && mutation.source === 'snapshot') {
616
+ continue;
617
+ }
618
+ lastMutationIndexByKey.set(`${mutation.collection}\u0001${mutation.index}`, mutationIndex);
619
+ }
620
+ for (let mutationIndex = 0; mutationIndex < mutations.length; mutationIndex += 1) {
621
+ const mutation = mutations[mutationIndex];
622
+ if (!shouldEmitSnapshotMutations && mutation.source === 'snapshot') {
623
+ continue;
624
+ }
625
+ const coalesceKey = `${mutation.collection}\u0001${mutation.index}`;
626
+ if (lastMutationIndexByKey.get(coalesceKey) !== mutationIndex) {
627
+ continue;
628
+ }
629
+ try {
630
+ const event = parseChatEventFromAppStateMutation(mutation);
631
+ if (!event) {
632
+ continue;
633
+ }
634
+ this.emit('chat_event', event);
635
+ }
636
+ catch (error) {
637
+ this.logger.debug('failed to parse chat event from app-state mutation', {
638
+ collection: mutation.collection,
639
+ source: mutation.source,
640
+ index: mutation.index,
641
+ message: toError(error).message
642
+ });
643
+ }
644
+ }
645
+ }
646
+ }
647
+ async startCommsWithCredentials(credentials) {
648
+ this.logger.debug('starting comms with credentials', {
649
+ registered: credentials.meJid !== null && credentials.meJid !== undefined
650
+ });
651
+ const commsConfig = this.authClient.buildCommsConfig(this.options);
652
+ const comms = new WaComms(commsConfig, this.logger);
653
+ this.mediaConnCache = null;
654
+ this.nodeTransport.bindComms(comms);
655
+ try {
656
+ comms.startComms(async (frame) => this.handleIncomingFrame(frame));
657
+ await comms.waitForConnection(commsConfig.connectTimeoutMs);
658
+ this.comms = comms;
659
+ this.logger.info('comms connected');
660
+ comms.startHandlingRequests();
661
+ if (credentials.meJid) {
662
+ this.keepAlive.start();
663
+ }
664
+ else {
665
+ this.keepAlive.stop();
666
+ }
667
+ const serverStaticKey = comms.getServerStaticKey();
668
+ if (!serverStaticKey) {
669
+ this.logger.trace('no server static key available to persist');
670
+ }
671
+ else {
672
+ await this.authClient.persistServerStaticKey(serverStaticKey);
673
+ this.logger.debug('persisted server static key after comms connect');
674
+ }
675
+ this.passiveTasks.startPassiveTasksAfterConnect();
676
+ }
677
+ catch (error) {
678
+ this.clearCommsBinding();
679
+ try {
680
+ await comms.stopComms();
681
+ }
682
+ catch (stopError) {
683
+ this.logger.warn('failed to cleanup comms after connection start failure', {
684
+ message: toError(stopError).message
685
+ });
686
+ }
687
+ throw error;
688
+ }
689
+ }
690
+ shouldQueueDanglingReceipt(node, error) {
691
+ if (node.tag !== WA_MESSAGE_TAGS.RECEIPT) {
692
+ return false;
693
+ }
694
+ const normalized = error.message.trim().toLowerCase();
695
+ return (normalized === 'comms is not connected' ||
696
+ normalized === 'websocket is not connected' ||
697
+ normalized === 'noise session socket closed' ||
698
+ normalized.startsWith('socket closed ('));
699
+ }
700
+ enqueueDanglingReceipt(node) {
701
+ if (this.danglingReceipts.length >= WA_DEFAULTS.MAX_DANGLING_RECEIPTS) {
702
+ this.danglingReceipts.shift();
703
+ }
704
+ this.danglingReceipts.push(node.content === undefined
705
+ ? {
706
+ tag: node.tag,
707
+ attrs: { ...node.attrs }
708
+ }
709
+ : {
710
+ tag: node.tag,
711
+ attrs: { ...node.attrs },
712
+ content: node.content
713
+ });
714
+ }
715
+ async clearStoredState() {
716
+ await this.authClient.clearStoredCredentials();
717
+ await this.appStateStore.clear();
718
+ await this.contactStore.clear();
719
+ await this.messageStore.clear();
720
+ await this.participantsStore.clear();
721
+ await this.deviceListStore.clear();
722
+ await this.retryStore.clear();
723
+ await this.signalStore.clear();
724
+ await this.senderKeyStore.clear();
725
+ await this.threadStore.clear();
726
+ }
727
+ handleError(error) {
728
+ this.logger.error('wa client error', { message: error.message });
729
+ this.emit('client_error', { error });
730
+ }
731
+ clearCommsBinding() {
732
+ this.notifyAppStateKeyShareWaiters(false);
733
+ this.comms = null;
734
+ this.nodeTransport.bindComms(null);
735
+ }
736
+ updateClockSkewFromSuccess(serverUnixSeconds) {
737
+ const serverMs = serverUnixSeconds * 1000;
738
+ const nowMs = Date.now();
739
+ this.clockSkewMs = serverMs - nowMs;
740
+ this.logger.debug('updated clock skew from success', {
741
+ serverUnixSeconds,
742
+ clockSkewMs: this.clockSkewMs
743
+ });
744
+ }
745
+ }