zapo-js 0.2.0 → 0.3.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 (351) hide show
  1. package/README.md +7 -3
  2. package/dist/appstate/WaAppStateCrypto.js +49 -41
  3. package/dist/appstate/WaAppStateSyncClient.js +79 -42
  4. package/dist/appstate/index.js +2 -2
  5. package/dist/auth/WaAuthClient.js +20 -11
  6. package/dist/auth/{flow/WaAuthCredentialsFlow.js → credentials-flow.js} +83 -18
  7. package/dist/auth/pairing/WaPairingFlow.js +26 -29
  8. package/dist/auth/pairing/{WaPairingCodeCrypto.js → pairing-code-crypto.js} +29 -13
  9. package/dist/client/WaClient.js +115 -75
  10. package/dist/client/WaClientFactory.js +113 -30
  11. package/dist/client/connection/WaConnectionManager.js +4 -1
  12. package/dist/client/coordinators/WaAbPropsCoordinator.js +141 -0
  13. package/dist/client/coordinators/WaBusinessCoordinator.js +3 -12
  14. package/dist/client/coordinators/WaEmailCoordinator.js +63 -0
  15. package/dist/client/coordinators/WaIncomingNodeCoordinator.js +33 -8
  16. package/dist/client/coordinators/WaMessageDispatchCoordinator.js +55 -25
  17. package/dist/client/coordinators/WaOfflineResumeCoordinator.js +114 -0
  18. package/dist/client/coordinators/WaPassiveTasksCoordinator.js +38 -20
  19. package/dist/client/coordinators/WaProfileCoordinator.js +3 -1
  20. package/dist/client/coordinators/WaRetryCoordinator.js +11 -9
  21. package/dist/client/coordinators/WaTrustedContactTokenCoordinator.js +22 -4
  22. package/dist/client/dirty.js +1 -1
  23. package/dist/client/events/abprops.js +43 -0
  24. package/dist/client/events/privacy-token.js +1 -2
  25. package/dist/client/events/registration.js +42 -0
  26. package/dist/client/incoming.js +37 -0
  27. package/dist/client/mailbox.js +17 -1
  28. package/dist/client/media.js +243 -0
  29. package/dist/client/messages.js +163 -86
  30. package/dist/crypto/core/index.js +4 -1
  31. package/dist/crypto/core/random.js +3 -9
  32. package/dist/crypto/core/xeddsa.js +57 -0
  33. package/dist/crypto/curves/X25519.js +18 -0
  34. package/dist/crypto/curves/constants.js +2 -1
  35. package/dist/esm/appstate/WaAppStateCrypto.js +39 -31
  36. package/dist/esm/appstate/WaAppStateSyncClient.js +68 -31
  37. package/dist/esm/appstate/index.js +1 -1
  38. package/dist/esm/appstate/{WaAppStateSyncResponseParser.js → response-parser.js} +1 -1
  39. package/dist/esm/auth/WaAuthClient.js +17 -8
  40. package/dist/esm/auth/{flow/WaAuthCredentialsFlow.js → credentials-flow.js} +83 -18
  41. package/dist/esm/auth/pairing/WaPairingFlow.js +25 -28
  42. package/dist/esm/auth/pairing/{WaPairingCodeCrypto.js → pairing-code-crypto.js} +20 -6
  43. package/dist/esm/client/WaClient.js +116 -76
  44. package/dist/esm/client/WaClientFactory.js +114 -31
  45. package/dist/esm/client/connection/WaConnectionManager.js +4 -1
  46. package/dist/esm/client/coordinators/WaAbPropsCoordinator.js +137 -0
  47. package/dist/esm/client/coordinators/WaBusinessCoordinator.js +4 -13
  48. package/dist/esm/client/coordinators/WaEmailCoordinator.js +60 -0
  49. package/dist/esm/client/coordinators/WaIncomingNodeCoordinator.js +35 -10
  50. package/dist/esm/client/coordinators/WaMessageDispatchCoordinator.js +47 -17
  51. package/dist/esm/client/coordinators/WaOfflineResumeCoordinator.js +110 -0
  52. package/dist/esm/client/coordinators/WaPassiveTasksCoordinator.js +38 -20
  53. package/dist/esm/client/coordinators/WaProfileCoordinator.js +3 -1
  54. package/dist/esm/client/coordinators/WaRetryCoordinator.js +11 -9
  55. package/dist/esm/client/coordinators/WaTrustedContactTokenCoordinator.js +24 -6
  56. package/dist/esm/client/dirty.js +1 -1
  57. package/dist/esm/client/events/abprops.js +40 -0
  58. package/dist/esm/client/events/privacy-token.js +1 -2
  59. package/dist/esm/client/events/registration.js +39 -0
  60. package/dist/esm/client/incoming.js +36 -0
  61. package/dist/esm/client/mailbox.js +17 -1
  62. package/dist/esm/client/media.js +234 -0
  63. package/dist/esm/client/messages.js +162 -85
  64. package/dist/esm/crypto/core/index.js +1 -0
  65. package/dist/esm/crypto/core/random.js +2 -7
  66. package/dist/esm/crypto/core/xeddsa.js +53 -0
  67. package/dist/esm/crypto/curves/X25519.js +20 -2
  68. package/dist/esm/crypto/curves/constants.js +1 -0
  69. package/dist/esm/infra/perf/StoreLock.js +7 -4
  70. package/dist/esm/media/WaMediaCrypto.js +257 -62
  71. package/dist/esm/media/WaMediaTransferClient.js +47 -190
  72. package/dist/esm/media/constants.js +2 -0
  73. package/dist/esm/media/processor.js +1 -0
  74. package/dist/esm/message/addon-crypto.js +130 -3
  75. package/dist/esm/message/content.js +12 -6
  76. package/dist/esm/message/icdc.js +8 -8
  77. package/dist/esm/message/incoming.js +14 -12
  78. package/dist/esm/message/phash.js +32 -12
  79. package/dist/esm/message/reporting-token.js +3 -3
  80. package/dist/esm/message/use-case-secret.js +1 -1
  81. package/dist/esm/protocol/abprops.js +159 -0
  82. package/dist/esm/protocol/browser.js +14 -0
  83. package/dist/esm/protocol/constants.js +3 -1
  84. package/dist/esm/protocol/email.js +30 -0
  85. package/dist/esm/protocol/jid.js +44 -10
  86. package/dist/esm/protocol/nodes.js +6 -2
  87. package/dist/esm/protocol/notification.js +7 -1
  88. package/dist/esm/retry/reason.js +1 -1
  89. package/dist/esm/signal/api/SignalDeviceSyncApi.js +5 -2
  90. package/dist/esm/signal/api/SignalDigestSyncApi.js +8 -6
  91. package/dist/esm/signal/api/SignalIdentitySyncApi.js +4 -4
  92. package/dist/esm/signal/api/SignalMissingPreKeysSyncApi.js +1 -1
  93. package/dist/esm/signal/api/SignalSessionSyncApi.js +1 -1
  94. package/dist/esm/signal/crypto/WaAdvSignature.js +5 -51
  95. package/dist/esm/signal/crypto/constants.js +0 -4
  96. package/dist/esm/signal/encoding.js +11 -54
  97. package/dist/esm/signal/group/SenderKeyChain.js +3 -3
  98. package/dist/esm/signal/group/SenderKeyCodec.js +5 -6
  99. package/dist/esm/signal/group/SenderKeyManager.js +13 -10
  100. package/dist/esm/signal/registration/keygen.js +2 -3
  101. package/dist/esm/signal/registration/utils.js +2 -2
  102. package/dist/esm/signal/session/SignalProtocol.js +18 -17
  103. package/dist/esm/signal/session/SignalRatchet.js +21 -10
  104. package/dist/esm/signal/session/SignalSerializer.js +5 -6
  105. package/dist/esm/signal/session/SignalSession.js +11 -9
  106. package/dist/esm/signal/session/resolver.js +6 -6
  107. package/dist/esm/store/contracts/identity.store.js +1 -0
  108. package/dist/esm/store/contracts/message-secret.store.js +1 -0
  109. package/dist/esm/store/contracts/pre-key.store.js +1 -0
  110. package/dist/esm/store/contracts/session.store.js +1 -0
  111. package/dist/esm/store/createStore.js +48 -12
  112. package/dist/esm/store/index.js +4 -0
  113. package/dist/esm/store/locks/identity.lock.js +16 -0
  114. package/dist/esm/store/locks/message-secret.lock.js +17 -0
  115. package/dist/esm/store/locks/pre-key.lock.js +27 -0
  116. package/dist/esm/store/locks/session.lock.js +19 -0
  117. package/dist/esm/store/locks/signal.lock.js +0 -24
  118. package/dist/esm/store/noop.store.js +20 -0
  119. package/dist/esm/store/providers/memory/device-list.store.js +3 -0
  120. package/dist/esm/store/providers/memory/identity.store.js +31 -0
  121. package/dist/esm/store/providers/memory/message-secret.store.js +81 -0
  122. package/dist/esm/store/providers/memory/participants.store.js +3 -0
  123. package/dist/esm/store/providers/memory/pre-key.store.js +97 -0
  124. package/dist/esm/store/providers/memory/retry.store.js +25 -11
  125. package/dist/esm/store/providers/memory/session.store.js +45 -0
  126. package/dist/esm/store/providers/memory/signal.store.js +1 -164
  127. package/dist/esm/transport/WaComms.js +4 -3
  128. package/dist/esm/transport/WaWebSocket.js +9 -1
  129. package/dist/esm/transport/index.js +6 -0
  130. package/dist/esm/transport/keepalive/WaKeepAlive.js +17 -8
  131. package/dist/esm/transport/node/WaMobileTcpSocket.js +114 -0
  132. package/dist/esm/transport/node/WaNodeOrchestrator.js +17 -8
  133. package/dist/esm/transport/node/builders/abprops.js +20 -0
  134. package/dist/esm/transport/node/builders/device.js +11 -0
  135. package/dist/esm/transport/node/builders/email.js +65 -0
  136. package/dist/esm/transport/node/builders/offline.js +14 -0
  137. package/dist/esm/transport/node/builders/prekeys.js +37 -40
  138. package/dist/esm/transport/node/builders/presence.js +13 -0
  139. package/dist/esm/transport/node/builders/privacy-token.js +19 -23
  140. package/dist/esm/transport/node/builders/retry.js +1 -1
  141. package/dist/esm/transport/node/helpers.js +24 -0
  142. package/dist/esm/transport/node/mex/argo-decoder.js +152 -0
  143. package/dist/esm/transport/node/mex/client.js +83 -0
  144. package/dist/esm/transport/node/mex/persist-ids.js +10 -0
  145. package/dist/esm/transport/noise/WaClientPayload.js +15 -10
  146. package/dist/esm/transport/noise/WaFrameCodec.js +2 -2
  147. package/dist/esm/transport/noise/WaMobileClientPayload.js +53 -0
  148. package/dist/esm/transport/noise/WaNoiseCert.js +9 -27
  149. package/dist/esm/transport/noise/WaNoiseSession.js +12 -11
  150. package/dist/infra/perf/StoreLock.js +7 -4
  151. package/dist/media/WaMediaCrypto.js +253 -58
  152. package/dist/media/WaMediaTransferClient.js +50 -223
  153. package/dist/media/constants.js +3 -1
  154. package/dist/media/processor.js +2 -0
  155. package/dist/message/addon-crypto.js +131 -0
  156. package/dist/message/content.js +13 -5
  157. package/dist/message/icdc.js +8 -8
  158. package/dist/message/incoming.js +14 -12
  159. package/dist/message/phash.js +32 -12
  160. package/dist/message/reporting-token.js +2 -2
  161. package/dist/message/use-case-secret.js +1 -1
  162. package/dist/protocol/abprops.js +163 -0
  163. package/dist/protocol/browser.js +15 -0
  164. package/dist/protocol/constants.js +14 -2
  165. package/dist/protocol/email.js +33 -0
  166. package/dist/protocol/jid.js +45 -10
  167. package/dist/protocol/nodes.js +6 -2
  168. package/dist/protocol/notification.js +8 -2
  169. package/dist/retry/reason.js +1 -1
  170. package/dist/signal/api/SignalDeviceSyncApi.js +5 -2
  171. package/dist/signal/api/SignalDigestSyncApi.js +8 -6
  172. package/dist/signal/api/SignalIdentitySyncApi.js +4 -4
  173. package/dist/signal/crypto/WaAdvSignature.js +2 -50
  174. package/dist/signal/crypto/constants.js +1 -5
  175. package/dist/signal/encoding.js +11 -49
  176. package/dist/signal/group/SenderKeyChain.js +2 -2
  177. package/dist/signal/group/SenderKeyCodec.js +4 -5
  178. package/dist/signal/group/SenderKeyManager.js +12 -9
  179. package/dist/signal/registration/keygen.js +1 -2
  180. package/dist/signal/registration/utils.js +2 -2
  181. package/dist/signal/session/SignalProtocol.js +18 -17
  182. package/dist/signal/session/SignalRatchet.js +19 -8
  183. package/dist/signal/session/SignalSerializer.js +5 -6
  184. package/dist/signal/session/SignalSession.js +11 -9
  185. package/dist/signal/session/resolver.js +6 -6
  186. package/dist/store/contracts/identity.store.js +2 -0
  187. package/dist/store/contracts/message-secret.store.js +2 -0
  188. package/dist/store/contracts/pre-key.store.js +2 -0
  189. package/dist/store/contracts/session.store.js +2 -0
  190. package/dist/store/createStore.js +47 -11
  191. package/dist/store/index.js +9 -1
  192. package/dist/store/locks/identity.lock.js +19 -0
  193. package/dist/store/locks/message-secret.lock.js +20 -0
  194. package/dist/store/locks/pre-key.lock.js +30 -0
  195. package/dist/store/locks/session.lock.js +22 -0
  196. package/dist/store/locks/signal.lock.js +0 -24
  197. package/dist/store/noop.store.js +21 -1
  198. package/dist/store/providers/memory/device-list.store.js +3 -0
  199. package/dist/store/providers/memory/identity.store.js +35 -0
  200. package/dist/store/providers/memory/message-secret.store.js +85 -0
  201. package/dist/store/providers/memory/participants.store.js +3 -0
  202. package/dist/store/providers/memory/pre-key.store.js +101 -0
  203. package/dist/store/providers/memory/retry.store.js +24 -10
  204. package/dist/store/providers/memory/session.store.js +49 -0
  205. package/dist/store/providers/memory/signal.store.js +1 -164
  206. package/dist/transport/WaComms.js +4 -3
  207. package/dist/transport/WaWebSocket.js +9 -1
  208. package/dist/transport/index.js +17 -1
  209. package/dist/transport/keepalive/WaKeepAlive.js +17 -8
  210. package/dist/transport/node/WaMobileTcpSocket.js +118 -0
  211. package/dist/transport/node/WaNodeOrchestrator.js +16 -7
  212. package/dist/transport/node/builders/abprops.js +23 -0
  213. package/dist/transport/node/builders/device.js +14 -0
  214. package/dist/transport/node/builders/email.js +72 -0
  215. package/dist/transport/node/builders/offline.js +17 -0
  216. package/dist/transport/node/builders/prekeys.js +36 -39
  217. package/dist/transport/node/builders/presence.js +16 -0
  218. package/dist/transport/node/builders/privacy-token.js +18 -22
  219. package/dist/transport/node/builders/retry.js +1 -1
  220. package/dist/transport/node/helpers.js +26 -0
  221. package/dist/transport/node/mex/argo-decoder.js +189 -0
  222. package/dist/transport/node/mex/client.js +86 -0
  223. package/dist/transport/node/mex/persist-ids.js +13 -0
  224. package/dist/transport/noise/WaClientPayload.js +14 -9
  225. package/dist/transport/noise/WaFrameCodec.js +1 -1
  226. package/dist/transport/noise/WaMobileClientPayload.js +56 -0
  227. package/dist/transport/noise/WaNoiseCert.js +8 -26
  228. package/dist/transport/noise/WaNoiseSession.js +11 -10
  229. package/dist/types/appstate/WaAppStateCrypto.d.ts +11 -8
  230. package/dist/types/appstate/WaAppStateSyncClient.d.ts +6 -2
  231. package/dist/types/appstate/index.d.ts +1 -1
  232. package/dist/types/appstate/{WaAppStateSyncResponseParser.d.ts → response-parser.d.ts} +1 -1
  233. package/dist/types/appstate/types.d.ts +1 -1
  234. package/dist/types/auth/WaAuthClient.d.ts +9 -3
  235. package/dist/types/auth/credentials-flow.d.ts +20 -0
  236. package/dist/types/auth/pairing/WaPairingFlow.d.ts +3 -2
  237. package/dist/types/auth/pairing/{WaPairingCodeCrypto.d.ts → pairing-code-crypto.d.ts} +6 -1
  238. package/dist/types/auth/types.d.ts +40 -0
  239. package/dist/types/client/WaClient.d.ts +19 -8
  240. package/dist/types/client/WaClientFactory.d.ts +10 -4
  241. package/dist/types/client/coordinators/WaAbPropsCoordinator.d.ts +26 -0
  242. package/dist/types/client/coordinators/WaBusinessCoordinator.d.ts +1 -1
  243. package/dist/types/client/coordinators/WaEmailCoordinator.d.ts +24 -0
  244. package/dist/types/client/coordinators/WaIncomingNodeCoordinator.d.ts +6 -1
  245. package/dist/types/client/coordinators/WaMessageDispatchCoordinator.d.ts +15 -2
  246. package/dist/types/client/coordinators/WaOfflineResumeCoordinator.d.ts +31 -0
  247. package/dist/types/client/coordinators/WaPassiveTasksCoordinator.d.ts +13 -2
  248. package/dist/types/client/coordinators/WaPrivacyCoordinator.d.ts +1 -1
  249. package/dist/types/client/coordinators/WaProfileCoordinator.d.ts +4 -2
  250. package/dist/types/client/coordinators/WaRetryCoordinator.d.ts +6 -0
  251. package/dist/types/client/coordinators/WaTrustedContactTokenCoordinator.d.ts +11 -1
  252. package/dist/types/client/dirty.d.ts +3 -1
  253. package/dist/types/client/events/abprops.d.ts +14 -0
  254. package/dist/types/client/events/registration.d.ts +17 -0
  255. package/dist/types/client/incoming.d.ts +6 -1
  256. package/dist/types/client/mailbox.d.ts +2 -0
  257. package/dist/types/client/media.d.ts +31 -0
  258. package/dist/types/client/messages.d.ts +2 -0
  259. package/dist/types/client/persistence/WriteBehindPersistence.d.ts +1 -1
  260. package/dist/types/client/types.d.ts +100 -1
  261. package/dist/types/crypto/core/index.d.ts +1 -0
  262. package/dist/types/crypto/core/primitives.d.ts +1 -1
  263. package/dist/types/crypto/core/random.d.ts +1 -1
  264. package/dist/types/crypto/core/xeddsa.d.ts +2 -0
  265. package/dist/types/crypto/curves/constants.d.ts +1 -0
  266. package/dist/types/crypto/index.d.ts +1 -0
  267. package/dist/types/index.d.ts +2 -1
  268. package/dist/types/infra/log/ConsoleLogger.d.ts +1 -1
  269. package/dist/types/infra/log/PinoLogger.d.ts +1 -1
  270. package/dist/types/infra/perf/StoreLock.d.ts +1 -0
  271. package/dist/types/media/WaMediaCrypto.d.ts +15 -6
  272. package/dist/types/media/WaMediaTransferClient.d.ts +3 -11
  273. package/dist/types/media/constants.d.ts +2 -0
  274. package/dist/types/media/index.d.ts +1 -0
  275. package/dist/types/media/processor.d.ts +28 -0
  276. package/dist/types/media/types.d.ts +9 -3
  277. package/dist/types/message/addon-crypto.d.ts +34 -3
  278. package/dist/types/message/content.d.ts +3 -1
  279. package/dist/types/message/icdc.d.ts +4 -4
  280. package/dist/types/message/types.d.ts +16 -24
  281. package/dist/types/protocol/abprops.d.ts +142 -0
  282. package/dist/types/protocol/browser.d.ts +1 -0
  283. package/dist/types/protocol/constants.d.ts +5 -1
  284. package/dist/types/protocol/email.d.ts +32 -0
  285. package/dist/types/protocol/jid.d.ts +1 -0
  286. package/dist/types/protocol/nodes.d.ts +4 -0
  287. package/dist/types/protocol/notification.d.ts +6 -0
  288. package/dist/types/protocol/stream.d.ts +1 -0
  289. package/dist/types/retry/reason.d.ts +1 -1
  290. package/dist/types/signal/api/SignalDigestSyncApi.d.ts +3 -0
  291. package/dist/types/signal/api/SignalIdentitySyncApi.d.ts +3 -3
  292. package/dist/types/signal/crypto/WaAdvSignature.d.ts +0 -2
  293. package/dist/types/signal/crypto/constants.d.ts +0 -1
  294. package/dist/types/signal/encoding.d.ts +7 -1
  295. package/dist/types/signal/group/SenderKeyChain.d.ts +1 -1
  296. package/dist/types/signal/group/SenderKeyManager.d.ts +7 -2
  297. package/dist/types/signal/registration/utils.d.ts +2 -1
  298. package/dist/types/signal/session/SignalProtocol.d.ts +11 -2
  299. package/dist/types/signal/session/SignalSerializer.d.ts +2 -1
  300. package/dist/types/signal/session/resolver.d.ts +4 -2
  301. package/dist/types/signal/types.d.ts +16 -4
  302. package/dist/types/store/contracts/identity.store.d.ts +11 -0
  303. package/dist/types/store/contracts/message-secret.store.d.ts +16 -0
  304. package/dist/types/store/contracts/pre-key.store.d.ts +13 -0
  305. package/dist/types/store/contracts/session.store.d.ts +14 -0
  306. package/dist/types/store/contracts/signal.store.d.ts +1 -34
  307. package/dist/types/store/index.d.ts +9 -1
  308. package/dist/types/store/locks/identity.lock.d.ts +3 -0
  309. package/dist/types/store/locks/message-secret.lock.d.ts +3 -0
  310. package/dist/types/store/locks/pre-key.lock.d.ts +3 -0
  311. package/dist/types/store/locks/session.lock.d.ts +3 -0
  312. package/dist/types/store/noop.store.d.ts +4 -0
  313. package/dist/types/store/providers/memory/identity.store.d.ts +18 -0
  314. package/dist/types/store/providers/memory/message-secret.store.d.ts +21 -0
  315. package/dist/types/store/providers/memory/pre-key.store.d.ts +23 -0
  316. package/dist/types/store/providers/memory/retry.store.d.ts +7 -1
  317. package/dist/types/store/providers/memory/session.store.d.ts +21 -0
  318. package/dist/types/store/providers/memory/signal.store.d.ts +3 -45
  319. package/dist/types/store/providers/memory/thread.store.d.ts +1 -1
  320. package/dist/types/store/types.d.ts +21 -1
  321. package/dist/types/transport/WaWebSocket.d.ts +1 -0
  322. package/dist/types/transport/index.d.ts +8 -1
  323. package/dist/types/transport/keepalive/WaKeepAlive.d.ts +4 -1
  324. package/dist/types/transport/node/WaMobileTcpSocket.d.ts +18 -0
  325. package/dist/types/transport/node/WaNodeOrchestrator.d.ts +6 -2
  326. package/dist/types/transport/node/builders/abprops.d.ts +5 -0
  327. package/dist/types/transport/node/builders/device.d.ts +2 -0
  328. package/dist/types/transport/node/builders/email.d.ts +11 -0
  329. package/dist/types/transport/node/builders/offline.d.ts +2 -0
  330. package/dist/types/transport/node/builders/prekeys.d.ts +4 -3
  331. package/dist/types/transport/node/builders/presence.d.ts +6 -0
  332. package/dist/types/transport/node/helpers.d.ts +3 -0
  333. package/dist/types/transport/node/mex/argo-decoder.d.ts +11 -0
  334. package/dist/types/transport/node/mex/client.d.ts +18 -0
  335. package/dist/types/transport/node/mex/persist-ids.d.ts +14 -0
  336. package/dist/types/transport/noise/WaMobileClientPayload.d.ts +29 -0
  337. package/dist/types/transport/noise/WaNoiseCert.d.ts +7 -1
  338. package/dist/types/transport/noise/WaNoiseSession.d.ts +1 -0
  339. package/dist/types/transport/types.d.ts +8 -0
  340. package/package.json +6 -4
  341. package/dist/auth/pairing/constants.js +0 -5
  342. package/dist/client/connection/WaKeyShareCoordinator.js +0 -63
  343. package/dist/esm/auth/pairing/constants.js +0 -2
  344. package/dist/esm/client/connection/WaKeyShareCoordinator.js +0 -59
  345. package/dist/esm/transport/node/builders/index.js +0 -11
  346. package/dist/transport/node/builders/index.js +0 -51
  347. package/dist/types/auth/flow/WaAuthCredentialsFlow.d.ts +0 -14
  348. package/dist/types/auth/pairing/constants.d.ts +0 -2
  349. package/dist/types/client/connection/WaKeyShareCoordinator.d.ts +0 -14
  350. package/dist/types/transport/node/builders/index.d.ts +0 -11
  351. /package/dist/appstate/{WaAppStateSyncResponseParser.js → response-parser.js} +0 -0
@@ -200,7 +200,10 @@ export class WaConnectionManager {
200
200
  this.logger.debug('starting comms with credentials', {
201
201
  registered: credentials.meJid !== null && credentials.meJid !== undefined
202
202
  });
203
- const commsConfig = this.authClient.buildCommsConfig(this.options);
203
+ const commsConfig = this.authClient.buildCommsConfig(this.options, {
204
+ noiseTrustedRootCa: this.options.testHooks?.noiseRootCa,
205
+ disableNoiseCertificateChainVerification: this.options.dangerous?.disableNoiseCertificateChainVerification
206
+ });
204
207
  const comms = new WaComms(commsConfig, this.logger);
205
208
  this.pendingComms = comms;
206
209
  this.mediaConnCache = null;
@@ -0,0 +1,137 @@
1
+ import { parseAbPropsIqResult } from '../events/abprops.js';
2
+ import { AB_PROP_CONFIGS, resolveAbPropNameByCode, WA_ABPROPS_REFRESH_BOUNDS } from '../../protocol/abprops.js';
3
+ import { WA_DEFAULTS } from '../../protocol/constants.js';
4
+ import { buildGetAbPropsIq } from '../../transport/node/builders/abprops.js';
5
+ import { toError } from '../../util/primitives.js';
6
+ export class WaAbPropsCoordinator {
7
+ constructor(options) {
8
+ this.logger = options.logger;
9
+ this.runtime = options.runtime;
10
+ this.cache = new Map();
11
+ this.syncState = { hash: null, abKey: null, refreshId: null };
12
+ this.syncPromise = null;
13
+ this.syncEpoch = 0;
14
+ this.pendingSync = false;
15
+ }
16
+ getConfigValue(name) {
17
+ const cached = this.cache.get(name);
18
+ if (cached !== undefined) {
19
+ return cached;
20
+ }
21
+ return AB_PROP_CONFIGS[name].defaultValue;
22
+ }
23
+ sync() {
24
+ if (this.syncPromise) {
25
+ this.pendingSync = true;
26
+ return;
27
+ }
28
+ this.startSync();
29
+ }
30
+ reset() {
31
+ this.cache.clear();
32
+ this.syncState.hash = null;
33
+ this.syncState.abKey = null;
34
+ this.syncState.refreshId = null;
35
+ this.syncPromise = null;
36
+ this.pendingSync = false;
37
+ this.syncEpoch += 1;
38
+ }
39
+ startSync() {
40
+ const epoch = this.syncEpoch;
41
+ this.pendingSync = false;
42
+ this.syncPromise = this.executeSyncWithRetry(epoch)
43
+ .catch((error) => {
44
+ this.logger.warn('ab props sync failed', {
45
+ message: toError(error).message
46
+ });
47
+ })
48
+ .finally(() => {
49
+ if (this.syncEpoch !== epoch) {
50
+ return;
51
+ }
52
+ this.syncPromise = null;
53
+ if (this.pendingSync) {
54
+ this.startSync();
55
+ }
56
+ });
57
+ }
58
+ async executeSyncWithRetry(epoch) {
59
+ const maxRetries = 3;
60
+ for (let attempt = 0; attempt < maxRetries; attempt += 1) {
61
+ if (this.syncEpoch !== epoch) {
62
+ return;
63
+ }
64
+ try {
65
+ await this.executeSync(epoch);
66
+ return;
67
+ }
68
+ catch (error) {
69
+ if (attempt === maxRetries - 1) {
70
+ throw error;
71
+ }
72
+ this.logger.debug('ab props sync retrying', {
73
+ attempt: attempt + 1,
74
+ message: toError(error).message
75
+ });
76
+ }
77
+ }
78
+ }
79
+ async executeSync(epoch) {
80
+ const iqNode = buildGetAbPropsIq({
81
+ hash: this.syncState.hash,
82
+ refreshId: this.syncState.refreshId
83
+ });
84
+ const response = await this.runtime.queryWithContext('abprops.sync', iqNode, WA_DEFAULTS.IQ_TIMEOUT_MS);
85
+ if (this.syncEpoch !== epoch) {
86
+ return;
87
+ }
88
+ const result = parseAbPropsIqResult(response);
89
+ if (result.abKey !== null) {
90
+ this.syncState.abKey = result.abKey;
91
+ }
92
+ if (result.hash !== null) {
93
+ this.syncState.hash = result.hash;
94
+ }
95
+ if (result.refreshId !== null) {
96
+ this.syncState.refreshId = result.refreshId;
97
+ }
98
+ if (!result.isDeltaUpdate) {
99
+ this.cache.clear();
100
+ }
101
+ let applied = 0;
102
+ for (let i = 0; i < result.props.length; i += 1) {
103
+ const entry = result.props[i];
104
+ const name = resolveAbPropNameByCode(entry.configCode);
105
+ if (!name) {
106
+ continue;
107
+ }
108
+ const config = AB_PROP_CONFIGS[name];
109
+ const parsed = parseConfigValue(entry.configValue, config.type, config.defaultValue);
110
+ this.cache.set(name, parsed);
111
+ applied += 1;
112
+ }
113
+ this.logger.info('ab props synced', {
114
+ received: result.props.length,
115
+ applied,
116
+ isDelta: result.isDeltaUpdate,
117
+ abKey: result.abKey,
118
+ refresh: result.refresh !== null ? clampRefresh(result.refresh) : null
119
+ });
120
+ }
121
+ }
122
+ function parseConfigValue(value, type, defaultValue) {
123
+ if (value === null) {
124
+ return defaultValue;
125
+ }
126
+ if (type === 'bool') {
127
+ return value === '1' || value === 'true' || value === 'True';
128
+ }
129
+ if (type === 'int') {
130
+ const parsed = Number.parseInt(value, 10);
131
+ return Number.isSafeInteger(parsed) ? parsed : defaultValue;
132
+ }
133
+ return value;
134
+ }
135
+ function clampRefresh(seconds) {
136
+ return Math.max(WA_ABPROPS_REFRESH_BOUNDS.MIN_S, Math.min(WA_ABPROPS_REFRESH_BOUNDS.MAX_S, seconds));
137
+ }
@@ -1,17 +1,8 @@
1
1
  import { proto } from '../../proto.js';
2
2
  import { buildDeleteCoverPhotoIq, buildEditBusinessProfileIq, buildGetBusinessProfileIq, buildGetVerifiedNameIq, buildUpdateCoverPhotoIq } from '../../transport/node/builders/business.js';
3
- import { findNodeChild, getNodeChildren } from '../../transport/node/helpers.js';
3
+ import { findNodeChild, getNodeChildren, getNodeTextContent } from '../../transport/node/helpers.js';
4
4
  import { assertIqResult } from '../../transport/node/query.js';
5
- import { TEXT_DECODER } from '../../util/bytes.js';
6
5
  import { longToNumber } from '../../util/primitives.js';
7
- function readTextContent(node) {
8
- const content = node.content;
9
- if (content instanceof Uint8Array)
10
- return TEXT_DECODER.decode(content);
11
- if (typeof content === 'string')
12
- return content;
13
- return undefined;
14
- }
15
6
  function parseBusinessProfiles(result) {
16
7
  const bizNode = findNodeChild(result, 'business_profile');
17
8
  if (!bizNode) {
@@ -40,7 +31,7 @@ function parseBusinessProfiles(result) {
40
31
  const websites = [];
41
32
  for (let j = 0; j < children.length; j += 1) {
42
33
  const child = children[j];
43
- const text = readTextContent(child);
34
+ const text = getNodeTextContent(child);
44
35
  switch (child.tag) {
45
36
  case 'description':
46
37
  if (text !== undefined)
@@ -102,7 +93,7 @@ function parseBusinessCategories(node) {
102
93
  const id = child.attrs.id;
103
94
  if (!id)
104
95
  continue;
105
- categories[count] = { id, name: readTextContent(child) ?? '' };
96
+ categories[count] = { id, name: getNodeTextContent(child) ?? '' };
106
97
  count += 1;
107
98
  }
108
99
  categories.length = count;
@@ -139,7 +130,7 @@ function parseProfileOptions(node) {
139
130
  const options = {};
140
131
  for (let i = 0; i < children.length; i += 1) {
141
132
  const child = children[i];
142
- const text = readTextContent(child);
133
+ const text = getNodeTextContent(child);
143
134
  if (text !== undefined) {
144
135
  options[child.tag] = text;
145
136
  }
@@ -0,0 +1,60 @@
1
+ import { WA_EMAIL_TAGS } from '../../protocol/email.js';
2
+ import { buildConfirmEmailIq, buildGetEmailIq, buildRequestEmailVerificationCodeIq, buildSetEmailIq, buildVerifyEmailCodeIq } from '../../transport/node/builders/email.js';
3
+ import { findNodeChild, getNodeTextContent } from '../../transport/node/helpers.js';
4
+ import { assertIqResult } from '../../transport/node/query.js';
5
+ export function createEmailCoordinator(options) {
6
+ const { queryWithContext } = options;
7
+ return {
8
+ getStatus: async () => {
9
+ const result = await queryWithContext('email.getStatus', buildGetEmailIq());
10
+ assertIqResult(result, 'email.getStatus');
11
+ return parseEmailStatus(result);
12
+ },
13
+ setEmail: async (email, context) => {
14
+ const result = await queryWithContext('email.set', buildSetEmailIq(email, context), undefined, context !== undefined ? { context } : {});
15
+ assertIqResult(result, 'email.set');
16
+ return parseEmailStatus(result);
17
+ },
18
+ requestVerificationCode: async (input) => {
19
+ const result = await queryWithContext('email.requestCode', buildRequestEmailVerificationCodeIq(input), undefined, { languageCode: input.languageCode, localeCode: input.localeCode });
20
+ assertIqResult(result, 'email.requestCode');
21
+ },
22
+ verifyCode: async (code) => {
23
+ const result = await queryWithContext('email.verifyCode', buildVerifyEmailCodeIq(code));
24
+ assertIqResult(result, 'email.verifyCode');
25
+ return parseVerifyCodeResult(result);
26
+ },
27
+ confirm: async (context) => {
28
+ const result = await queryWithContext('email.confirm', buildConfirmEmailIq(context), undefined, context !== undefined ? { context } : {});
29
+ assertIqResult(result, 'email.confirm');
30
+ }
31
+ };
32
+ }
33
+ function parseEmailStatus(result) {
34
+ const emailNode = findNodeChild(result, WA_EMAIL_TAGS.EMAIL);
35
+ if (!emailNode) {
36
+ return { email: null, verified: false, confirmed: false };
37
+ }
38
+ const verifiedAttr = emailNode.attrs.verified;
39
+ const addressNode = findNodeChild(emailNode, WA_EMAIL_TAGS.EMAIL_ADDRESS);
40
+ const confirmedNode = findNodeChild(emailNode, WA_EMAIL_TAGS.CONFIRMED);
41
+ return {
42
+ email: addressNode ? (getNodeTextContent(addressNode) ?? null) : null,
43
+ verified: verifiedAttr === 'true',
44
+ confirmed: confirmedNode ? getNodeTextContent(confirmedNode) === 'true' : false
45
+ };
46
+ }
47
+ function parseVerifyCodeResult(result) {
48
+ const emailNode = findNodeChild(result, WA_EMAIL_TAGS.EMAIL);
49
+ if (!emailNode) {
50
+ return { verified: false, autoVerifyFailed: false, email: null };
51
+ }
52
+ const doVerify = emailNode.attrs.do_verify;
53
+ const autoVerifyNode = findNodeChild(emailNode, WA_EMAIL_TAGS.AUTO_VERIFY);
54
+ const addressNode = findNodeChild(emailNode, WA_EMAIL_TAGS.EMAIL_ADDRESS);
55
+ return {
56
+ verified: doVerify === 'true',
57
+ autoVerifyFailed: autoVerifyNode ? getNodeTextContent(autoVerifyNode) === 'fail' : false,
58
+ email: addressNode ? (getNodeTextContent(addressNode) ?? null) : null
59
+ };
60
+ }
@@ -1,9 +1,9 @@
1
- import { createIncomingBaseEvent, createIncomingFailureHandler, createIncomingGroupNotificationHandler, createIncomingNotificationHandler, createIncomingReceiptHandler, createInfoBulletinNotificationEvent, createUnhandledIncomingNodeEvent } from '../incoming.js';
1
+ import { createIncomingBaseEvent, createIncomingFailureHandler, createIncomingGroupNotificationHandler, createIncomingNotificationHandler, createIncomingReceiptHandler, createIncomingRegistrationNotificationHandler, createInfoBulletinNotificationEvent, createUnhandledIncomingNodeEvent } from '../incoming.js';
2
2
  import { WA_IQ_TYPES, WA_MESSAGE_TAGS, WA_NODE_TAGS, WA_NOTIFICATION_TYPES, WA_SIGNALING } from '../../protocol/constants.js';
3
- import { decodeNodeContentBase64OrBytes, findNodeChild, getNodeChildrenByTag } from '../../transport/node/helpers.js';
3
+ import { decodeNodeContentBase64OrBytes, findNodeChild, getNodeChildren, getNodeChildrenByTag } from '../../transport/node/helpers.js';
4
4
  import { parseStreamControlNode, parseSuccessPersistAttributes } from '../../transport/stream/parse.js';
5
5
  import { parseOptionalInt, toError } from '../../util/primitives.js';
6
- const INFO_BULLETIN_NOTIFICATION_TYPES = new Set([
6
+ const INFO_BULLETIN_CHILD_TAGS = new Set([
7
7
  'offline',
8
8
  'offline_preview',
9
9
  'priority_offline_complete',
@@ -15,6 +15,7 @@ export class WaIncomingNodeCoordinator {
15
15
  constructor(options) {
16
16
  this.logger = options.logger;
17
17
  this.runtime = options.runtime;
18
+ this.offlineResume = options.offlineResume;
18
19
  this.nodeHandlerRegistry = new Map();
19
20
  this.registerDefaultIncomingHandlers();
20
21
  this.mediaConnWarmupPromise = null;
@@ -25,6 +26,9 @@ export class WaIncomingNodeCoordinator {
25
26
  id: node.attrs.id,
26
27
  type: node.attrs.type
27
28
  });
29
+ if (node.attrs.offline !== undefined) {
30
+ this.offlineResume.trackOfflineStanza();
31
+ }
28
32
  const streamControlResult = parseStreamControlNode(node);
29
33
  if (streamControlResult) {
30
34
  await this.runtime.handleStreamControlResult(streamControlResult);
@@ -144,6 +148,16 @@ export class WaIncomingNodeCoordinator {
144
148
  emitUnhandledStanza: runtime.emitUnhandledIncomingNode
145
149
  })
146
150
  });
151
+ this.registerIncomingHandler({
152
+ tag: WA_NODE_TAGS.NOTIFICATION,
153
+ subtype: WA_NOTIFICATION_TYPES.REGISTRATION,
154
+ handler: createIncomingRegistrationNotificationHandler({
155
+ logger: this.logger,
156
+ sendNode: runtime.sendNode,
157
+ emitRegistrationCode: runtime.emitRegistrationCode,
158
+ emitAccountTakeoverNotice: runtime.emitAccountTakeoverNotice
159
+ })
160
+ });
147
161
  this.registerIncomingHandler({
148
162
  tag: WA_NODE_TAGS.NOTIFICATION,
149
163
  handler: createIncomingNotificationHandler({
@@ -263,13 +277,24 @@ export class WaIncomingNodeCoordinator {
263
277
  return false;
264
278
  }
265
279
  let handled = false;
266
- const ibType = node.attrs.type;
267
- if (ibType && INFO_BULLETIN_NOTIFICATION_TYPES.has(ibType)) {
268
- this.runtime.emitIncomingNotification(createInfoBulletinNotificationEvent(node, ibType, {
269
- count: parseOptionalInt(node.attrs.count),
270
- t: parseOptionalInt(node.attrs.t)
271
- }));
272
- handled = true;
280
+ const children = getNodeChildren(node);
281
+ for (const child of children) {
282
+ if (INFO_BULLETIN_CHILD_TAGS.has(child.tag)) {
283
+ this.runtime.emitIncomingNotification(createInfoBulletinNotificationEvent(node, child.tag, {
284
+ count: parseOptionalInt(child.attrs.count),
285
+ message: parseOptionalInt(child.attrs.message),
286
+ receipt: parseOptionalInt(child.attrs.receipt),
287
+ notification: parseOptionalInt(child.attrs.notification),
288
+ t: parseOptionalInt(child.attrs.t)
289
+ }));
290
+ if (child.tag === 'offline_preview') {
291
+ this.offlineResume.handleOfflinePreview(parseOptionalInt(child.attrs.count) ?? 0);
292
+ }
293
+ if (child.tag === 'offline') {
294
+ this.offlineResume.handleOfflineComplete(parseOptionalInt(child.attrs.count) ?? 0);
295
+ }
296
+ handled = true;
297
+ }
273
298
  }
274
299
  const edgeRoutingNode = findNodeChild(node, WA_NODE_TAGS.EDGE_ROUTING);
275
300
  if (edgeRoutingNode) {
@@ -1,7 +1,8 @@
1
1
  import { randomBytesAsync, sha256 } from '../../crypto/index.js';
2
+ import { md5Bytes } from '../../crypto/core/primitives.js';
2
3
  import { PromiseDedup } from '../../infra/perf/PromiseDedup.js';
3
4
  import { ensureMessageSecret } from '../../message/index.js';
4
- import { resolveEditAttr, resolveEncMediaType, resolveMessageTypeAttr, resolveMetaAttrs } from '../../message/content.js';
5
+ import { needsSecretPersistence, resolveEditAttr, resolveEncMediaType, resolveMessageTypeAttr, resolveMetaAttrs } from '../../message/content.js';
5
6
  import { wrapDeviceSentMessage } from '../../message/device-sent.js';
6
7
  import { injectDeviceListMetadata, resolveIcdcMeta } from '../../message/icdc.js';
7
8
  import { writeRandomPadMax16 } from '../../message/padding.js';
@@ -9,8 +10,7 @@ import { computePhashV2 } from '../../message/phash.js';
9
10
  import { buildReportingTokenArtifacts } from '../../message/reporting-token.js';
10
11
  import { proto } from '../../proto.js';
11
12
  import { WA_DEFAULTS } from '../../protocol/constants.js';
12
- import { isGroupJid, normalizeDeviceJid, normalizeRecipientJid, parseJidFull, parseSignalAddressFromJid, splitJid, toUserJid } from '../../protocol/jid.js';
13
- import { signalAddressKey } from '../../protocol/jid.js';
13
+ import { isGroupJid, isLidJid, normalizeDeviceJid, normalizeRecipientJid, parseJidFull, parseSignalAddressFromJid, signalAddressKey, toUserJid } from '../../protocol/jid.js';
14
14
  import { encodeBinaryNode } from '../../transport/binary/index.js';
15
15
  import { buildDirectMessageFanoutNode, buildGroupSenderKeyMessageNode, buildMetaNode } from '../../transport/node/builders/message.js';
16
16
  import { bytesToHex, concatBytes, TEXT_ENCODER } from '../../util/bytes.js';
@@ -31,12 +31,17 @@ export class WaMessageDispatchCoordinator {
31
31
  this.senderKeyManager = options.senderKeyManager;
32
32
  this.signalProtocol = options.signalProtocol;
33
33
  this.signalStore = options.signalStore;
34
+ this.sessionStore = options.sessionStore;
35
+ this.identityStore = options.identityStore;
34
36
  this.deviceListStore = options.deviceListStore;
37
+ this.messageSecretStore = options.messageSecretStore;
35
38
  this.getCurrentMeJid = options.getCurrentMeJid;
36
39
  this.getCurrentMeLid = options.getCurrentMeLid;
37
40
  this.getCurrentSignedIdentity = options.getCurrentSignedIdentity;
38
41
  this.resolvePrivacyTokenNode = options.resolvePrivacyTokenNode;
39
42
  this.onDirectMessageSent = options.onDirectMessageSent;
43
+ this.getIcdcHashLength = options.getIcdcHashLength;
44
+ this.mobileMessageIdFormat = options.mobileMessageIdFormat ?? false;
40
45
  }
41
46
  async publishMessageNode(node, options = {}) {
42
47
  this.logger.debug('wa client publish message node', {
@@ -129,6 +134,21 @@ export class WaMessageDispatchCoordinator {
129
134
  this.withResolvedMessageId(options)
130
135
  ]);
131
136
  const messageWithSecret = await ensureMessageSecret(message);
137
+ const rawSecret = messageWithSecret.messageContextInfo?.messageSecret;
138
+ if (rawSecret &&
139
+ rawSecret.length > 0 &&
140
+ sendOptions.id &&
141
+ needsSecretPersistence(messageWithSecret)) {
142
+ const meJid = this.getCurrentMeJid() ?? '';
143
+ void this.messageSecretStore
144
+ .set(sendOptions.id, { secret: rawSecret, senderJid: meJid })
145
+ .catch((error) => {
146
+ this.logger.warn('failed to persist outgoing message secret', {
147
+ id: sendOptions.id,
148
+ message: toError(error).message
149
+ });
150
+ });
151
+ }
132
152
  const meJid = this.getCurrentMeJid();
133
153
  const regInfo = meJid ? await this.signalStore.getRegistrationInfo() : null;
134
154
  const localPubKey = regInfo?.identityKeyPair.pubKey;
@@ -408,14 +428,8 @@ export class WaMessageDispatchCoordinator {
408
428
  }
409
429
  resolveGroupAddressingMode(participantUserJids, groupJid) {
410
430
  for (let index = 0; index < participantUserJids.length; index += 1) {
411
- const participantJid = participantUserJids[index];
412
- try {
413
- if (splitJid(participantJid).server === 'lid') {
414
- return 'lid';
415
- }
416
- }
417
- catch (error) {
418
- this.logger.trace('ignoring malformed participant jid in addressing mode resolution', { participantJid, message: toError(error).message });
431
+ if (isLidJid(participantUserJids[index])) {
432
+ return 'lid';
419
433
  }
420
434
  }
421
435
  this.logger.trace('group addressing mode resolved to pn (default)', {
@@ -511,7 +525,7 @@ export class WaMessageDispatchCoordinator {
511
525
  for (let index = 0; index < pendingTargets.length; index += 1) {
512
526
  pendingTargetAddresses[index] = pendingTargets[index].address;
513
527
  }
514
- const hasPendingSessions = await this.signalStore.hasSessions(pendingTargetAddresses);
528
+ const hasPendingSessions = await this.sessionStore.hasSessions(pendingTargetAddresses);
515
529
  const nextAvailableTargets = [];
516
530
  for (let index = 0; index < pendingTargets.length; index += 1) {
517
531
  if (hasPendingSessions[index]) {
@@ -719,9 +733,20 @@ export class WaMessageDispatchCoordinator {
719
733
  async generateOutgoingMessageId() {
720
734
  try {
721
735
  const meUserJid = toUserJid(this.requireCurrentMeJid('sendMessage'));
722
- const timestampSeconds = Math.floor(Date.now() / 1000);
723
736
  const timestampBytes = new Uint8Array(8);
724
- new DataView(timestampBytes.buffer, timestampBytes.byteOffset, timestampBytes.byteLength).setBigUint64(0, BigInt(timestampSeconds), false);
737
+ const dv = new DataView(timestampBytes.buffer, timestampBytes.byteOffset, timestampBytes.byteLength);
738
+ if (this.mobileMessageIdFormat) {
739
+ dv.setBigUint64(0, BigInt(Date.now()), false);
740
+ const entropy = concatBytes([
741
+ timestampBytes,
742
+ TEXT_ENCODER.encode(meUserJid),
743
+ await randomBytesAsync(16)
744
+ ]);
745
+ const digest = md5Bytes(entropy);
746
+ digest[0] = 0xac;
747
+ return bytesToHex(digest).toUpperCase();
748
+ }
749
+ dv.setBigUint64(0, BigInt(Math.floor(Date.now() / 1000)), false);
725
750
  const entropy = concatBytes([
726
751
  timestampBytes,
727
752
  TEXT_ENCODER.encode(meUserJid),
@@ -731,9 +756,14 @@ export class WaMessageDispatchCoordinator {
731
756
  return `3EB0${bytesToHex(digest.subarray(0, 9)).toUpperCase()}`;
732
757
  }
733
758
  catch (error) {
734
- this.logger.warn('failed to generate sha256 message id, falling back to random id', {
759
+ this.logger.warn('failed to generate message id, falling back to random', {
735
760
  message: toError(error).message
736
761
  });
762
+ if (this.mobileMessageIdFormat) {
763
+ const bytes = await randomBytesAsync(16);
764
+ bytes[0] = 0xac;
765
+ return bytesToHex(bytes).toUpperCase();
766
+ }
737
767
  return `3EB0${bytesToHex(await randomBytesAsync(8)).toUpperCase()}`;
738
768
  }
739
769
  }
@@ -762,7 +792,7 @@ export class WaMessageDispatchCoordinator {
762
792
  getEncodedSignedDeviceIdentity() {
763
793
  const signedIdentity = this.getCurrentSignedIdentity();
764
794
  if (!signedIdentity) {
765
- throw new Error('missing signed identity for pkmsg fanout');
795
+ return undefined;
766
796
  }
767
797
  return proto.ADVSignedDeviceIdentity.encode(signedIdentity).finish();
768
798
  }
@@ -774,7 +804,7 @@ export class WaMessageDispatchCoordinator {
774
804
  if (!snapshot || snapshot.deviceJids.length === 0) {
775
805
  return null;
776
806
  }
777
- return resolveIcdcMeta(snapshot.deviceJids, this.signalStore, snapshot.updatedAtMs, localIdentity);
807
+ return resolveIcdcMeta(snapshot.deviceJids, this.identityStore, snapshot.updatedAtMs, localIdentity, this.getIcdcHashLength?.());
778
808
  }
779
809
  catch (error) {
780
810
  this.logger.trace('icdc resolution failed', {
@@ -0,0 +1,110 @@
1
+ import { buildOfflineBatchNode } from '../../transport/node/builders/offline.js';
2
+ import { toError } from '../../util/primitives.js';
3
+ const WA_OFFLINE_RESUME = Object.freeze({
4
+ BATCH_SIZE: 200,
5
+ STANZA_TIMEOUT_MS: 60000
6
+ });
7
+ const WA_OFFLINE_RESUME_STATE = Object.freeze({
8
+ INIT: 'init',
9
+ RESUMING: 'resuming',
10
+ COMPLETE: 'complete'
11
+ });
12
+ export class WaOfflineResumeCoordinator {
13
+ constructor(options) {
14
+ this.logger = options.logger;
15
+ this.runtime = options.runtime;
16
+ this.state = WA_OFFLINE_RESUME_STATE.INIT;
17
+ this.totalStanzas = 0;
18
+ this.pendingStanzas = 0;
19
+ this.stanzaTimeout = null;
20
+ }
21
+ get isComplete() {
22
+ return this.state === WA_OFFLINE_RESUME_STATE.COMPLETE;
23
+ }
24
+ get isResuming() {
25
+ return this.state === WA_OFFLINE_RESUME_STATE.RESUMING;
26
+ }
27
+ handleOfflinePreview(stanzaCount) {
28
+ this.clearTimers();
29
+ this.state = WA_OFFLINE_RESUME_STATE.RESUMING;
30
+ this.totalStanzas = stanzaCount;
31
+ this.pendingStanzas = stanzaCount;
32
+ this.logger.info('offline resume started', {
33
+ totalStanzas: stanzaCount
34
+ });
35
+ this.runtime.emitOfflineResume({
36
+ status: 'resuming',
37
+ totalStanzas: stanzaCount,
38
+ remainingStanzas: stanzaCount,
39
+ forced: false
40
+ });
41
+ void this.sendOfflineBatch();
42
+ this.resetStanzaTimeout();
43
+ }
44
+ handleOfflineComplete(serverStanzaCount) {
45
+ if (this.state !== WA_OFFLINE_RESUME_STATE.RESUMING) {
46
+ return;
47
+ }
48
+ this.completeResume(false, serverStanzaCount);
49
+ }
50
+ trackOfflineStanza() {
51
+ if (this.state !== WA_OFFLINE_RESUME_STATE.RESUMING) {
52
+ return;
53
+ }
54
+ this.pendingStanzas = Math.max(0, this.pendingStanzas - 1);
55
+ this.resetStanzaTimeout();
56
+ }
57
+ reset() {
58
+ this.clearTimers();
59
+ this.state = WA_OFFLINE_RESUME_STATE.INIT;
60
+ this.totalStanzas = 0;
61
+ this.pendingStanzas = 0;
62
+ }
63
+ completeResume(forced, serverStanzaCount) {
64
+ this.clearTimers();
65
+ this.state = WA_OFFLINE_RESUME_STATE.COMPLETE;
66
+ this.logger.info('offline resume complete', {
67
+ totalStanzas: this.totalStanzas,
68
+ remainingStanzas: this.pendingStanzas,
69
+ serverStanzaCount,
70
+ forced
71
+ });
72
+ this.runtime.emitOfflineResume({
73
+ status: 'complete',
74
+ totalStanzas: this.totalStanzas,
75
+ remainingStanzas: this.pendingStanzas,
76
+ forced
77
+ });
78
+ }
79
+ async sendOfflineBatch() {
80
+ try {
81
+ await this.runtime.sendNode(buildOfflineBatchNode(WA_OFFLINE_RESUME.BATCH_SIZE));
82
+ }
83
+ catch (err) {
84
+ this.logger.warn('offline batch request failed', {
85
+ message: toError(err).message
86
+ });
87
+ }
88
+ }
89
+ resetStanzaTimeout() {
90
+ if (this.stanzaTimeout !== null) {
91
+ clearTimeout(this.stanzaTimeout);
92
+ }
93
+ this.stanzaTimeout = setTimeout(() => {
94
+ this.stanzaTimeout = null;
95
+ if (this.state === WA_OFFLINE_RESUME_STATE.RESUMING) {
96
+ this.logger.warn('offline resume forced complete due to stanza timeout', {
97
+ totalStanzas: this.totalStanzas,
98
+ remainingStanzas: this.pendingStanzas
99
+ });
100
+ this.completeResume(true);
101
+ }
102
+ }, WA_OFFLINE_RESUME.STANZA_TIMEOUT_MS);
103
+ }
104
+ clearTimers() {
105
+ if (this.stanzaTimeout !== null) {
106
+ clearTimeout(this.stanzaTimeout);
107
+ this.stanzaTimeout = null;
108
+ }
109
+ }
110
+ }