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
@@ -1,10 +1,10 @@
1
- import { Readable } from 'node:stream';
1
+ import http from 'node:http';
2
+ import https from 'node:https';
2
3
  import { DEFAULT_MEDIA_HOSTS } from './constants.js';
3
4
  import { WaMediaCrypto } from './WaMediaCrypto.js';
4
5
  import { WA_DEFAULTS } from '../protocol/constants.js';
5
6
  import { EMPTY_BYTES, readAllBytes } from '../util/bytes.js';
6
7
  import { toError } from '../util/primitives.js';
7
- const GOT_OPTIONAL_MODULE = 'got';
8
8
  function normalizeHeaderRecord(headers) {
9
9
  if (!headers) {
10
10
  return {};
@@ -15,56 +15,6 @@ function normalizeHeaderRecord(headers) {
15
15
  }
16
16
  return normalized;
17
17
  }
18
- function asOptionalGotModule(loaded) {
19
- if (loaded && typeof loaded === 'object') {
20
- const direct = loaded.stream;
21
- if (typeof direct === 'function') {
22
- return loaded;
23
- }
24
- const fallback = loaded.default;
25
- if (fallback &&
26
- typeof fallback === 'object' &&
27
- 'stream' in fallback &&
28
- typeof fallback.stream === 'function') {
29
- return fallback;
30
- }
31
- if (typeof fallback === 'function' && 'stream' in fallback) {
32
- const maybeStream = fallback.stream;
33
- if (typeof maybeStream === 'function') {
34
- return fallback;
35
- }
36
- }
37
- }
38
- if (typeof loaded === 'function' && 'stream' in loaded) {
39
- const maybeStream = loaded.stream;
40
- if (typeof maybeStream === 'function') {
41
- return loaded;
42
- }
43
- }
44
- return null;
45
- }
46
- async function loadOptionalGotModule() {
47
- try {
48
- const loaded = await import(GOT_OPTIONAL_MODULE);
49
- const module = asOptionalGotModule(loaded);
50
- if (module) {
51
- return module;
52
- }
53
- throw new Error('invalid got module export');
54
- }
55
- catch (error) {
56
- const normalized = toError(error);
57
- const code = normalized.code;
58
- const message = normalized.message ?? '';
59
- const isModuleNotFound = (code === 'ERR_MODULE_NOT_FOUND' || code === 'MODULE_NOT_FOUND') &&
60
- (message.includes(`'${GOT_OPTIONAL_MODULE}'`) ||
61
- message.includes(`"${GOT_OPTIONAL_MODULE}"`));
62
- if (isModuleNotFound) {
63
- throw new Error('optional dependency "got" is not installed. Install with: npm i got');
64
- }
65
- throw normalized;
66
- }
67
- }
68
18
  export class WaMediaTransferClient {
69
19
  constructor(options = {}) {
70
20
  this.logger = options.logger;
@@ -72,25 +22,18 @@ export class WaMediaTransferClient {
72
22
  this.defaultTimeoutMs = options.defaultTimeoutMs ?? WA_DEFAULTS.MEDIA_TIMEOUT_MS;
73
23
  this.defaultMaxReadBytes = options.defaultMaxReadBytes;
74
24
  this.defaultHeaders = normalizeHeaderRecord(options.defaultHeaders);
75
- this.defaultUploadDispatcher = options.defaultUploadDispatcher;
76
- this.defaultDownloadDispatcher = options.defaultDownloadDispatcher;
77
25
  this.defaultUploadAgent = options.defaultUploadAgent;
78
26
  this.defaultDownloadAgent = options.defaultDownloadAgent;
79
- this.gotModulePromise = null;
27
+ this.skipMacVerification = options.skipMacVerification === true;
80
28
  }
81
29
  async downloadStream(request) {
82
30
  const { urls, headers, timeoutMs } = this.resolveTransferRequest(request);
83
- const dispatcher = request.dispatcher ?? this.defaultDownloadDispatcher;
84
31
  const agent = request.agent ?? this.defaultDownloadAgent;
85
32
  this.logger?.debug('media download stream start', {
86
33
  urls: urls.length,
87
34
  timeoutMs
88
35
  });
89
- const result = await this.fetchWithFallback(urls, timeoutMs, request.signal, (url, signal) => this.transferRequest(url, {
90
- method: 'GET',
91
- headers,
92
- signal
93
- }, dispatcher, agent));
36
+ const result = await this.fetchWithFallback(urls, timeoutMs, request.signal, (url, signal) => this.httpRequest(url, { method: 'GET', headers, signal }, agent));
94
37
  this.logger?.trace('media download stream response', {
95
38
  url: result.url,
96
39
  status: result.status
@@ -115,7 +58,6 @@ export class WaMediaTransferClient {
115
58
  ? String(request.contentLength)
116
59
  : undefined
117
60
  });
118
- const dispatcher = request.dispatcher ?? this.defaultUploadDispatcher;
119
61
  const agent = request.agent ?? this.defaultUploadAgent;
120
62
  const uploadUrls = bodyIsBytes ? urls : urls.slice(0, 1);
121
63
  if (!bodyIsBytes && urls.length > 1) {
@@ -129,23 +71,7 @@ export class WaMediaTransferClient {
129
71
  timeoutMs,
130
72
  method
131
73
  });
132
- const result = await this.fetchWithFallback(uploadUrls, timeoutMs, request.signal, async (url, signal) => {
133
- if (bodyIsBytes) {
134
- return this.transferRequest(url, {
135
- method,
136
- headers,
137
- signal,
138
- body: request.body
139
- }, dispatcher, agent);
140
- }
141
- return this.transferRequest(url, {
142
- method,
143
- headers,
144
- signal,
145
- body: request.body,
146
- duplex: 'half'
147
- }, dispatcher, agent);
148
- });
74
+ const result = await this.fetchWithFallback(uploadUrls, timeoutMs, request.signal, (url, signal) => this.httpRequest(url, { method, headers, signal, body: request.body }, agent));
149
75
  this.logger?.trace('media upload stream response', {
150
76
  url: result.url,
151
77
  status: result.status
@@ -165,7 +91,6 @@ export class WaMediaTransferClient {
165
91
  directPath: request.directPath,
166
92
  hosts: request.hosts,
167
93
  headers: request.headers,
168
- dispatcher: request.dispatcher,
169
94
  agent: request.agent,
170
95
  timeoutMs: request.timeoutMs,
171
96
  signal: request.signal,
@@ -221,7 +146,8 @@ export class WaMediaTransferClient {
221
146
  mediaType: request.mediaType,
222
147
  mediaKey: request.mediaKey,
223
148
  expectedFileSha256: request.fileSha256,
224
- expectedFileEncSha256: request.fileEncSha256
149
+ expectedFileEncSha256: request.fileEncSha256,
150
+ skipMacVerification: this.skipMacVerification
225
151
  });
226
152
  decrypted.metadata.catch(() => undefined);
227
153
  this.logger?.debug('media encrypted download stream ready', {
@@ -238,119 +164,50 @@ export class WaMediaTransferClient {
238
164
  }
239
165
  return readAllBytes(response.body, { maxBytes: maxBytes ?? this.defaultMaxReadBytes });
240
166
  }
241
- async transferRequest(url, init, dispatcher, agent) {
242
- if (agent) {
243
- return this.gotWithAgent(url, init, agent);
244
- }
245
- return this.fetchWithDispatcher(url, init, dispatcher);
246
- }
247
- async fetchWithDispatcher(url, init, dispatcher) {
248
- const response = !dispatcher
249
- ? await fetch(url, init)
250
- : await fetch(url, {
251
- ...init,
252
- dispatcher
253
- });
254
- return this.toFetchTransferResponse(response);
255
- }
256
- toFetchTransferResponse(response) {
257
- return {
258
- status: response.status,
259
- ok: response.ok,
260
- headers: Object.fromEntries(response.headers.entries()),
261
- body: response.body
262
- ? Readable.fromWeb(response.body)
263
- : null,
264
- cancel: async () => {
265
- if (!response.body) {
266
- return;
267
- }
268
- try {
269
- await response.body.cancel();
270
- }
271
- catch {
272
- // ignore cancel errors from remote resets
273
- }
274
- }
275
- };
276
- }
277
- async gotWithAgent(url, init, agent) {
278
- const got = await this.loadGotModule();
279
- const urlObj = new URL(url);
280
- const gotAgent = urlObj.protocol === 'http:'
281
- ? { http: agent }
282
- : urlObj.protocol === 'https:'
283
- ? { https: agent }
284
- : { http: agent, https: agent };
167
+ async httpRequest(url, init, agent) {
168
+ const parsed = new URL(url);
169
+ const transport = parsed.protocol === 'https:' ? https : http;
285
170
  return new Promise((resolve, reject) => {
286
- const request = got.stream(url, {
287
- method: init.method,
288
- headers: (init.headers ?? {}),
289
- body: init.body,
290
- signal: init.signal,
291
- throwHttpErrors: false,
292
- retry: { limit: 0 },
293
- agent: gotAgent
294
- });
295
- const onError = (error) => {
296
- request.off('response', onResponse);
297
- reject(toError(error));
298
- };
299
- const onResponse = (incoming) => {
300
- request.off('error', onError);
301
- resolve(this.toGotTransferResponse(incoming));
302
- };
303
- request.once('error', onError);
304
- request.once('response', onResponse);
305
- });
306
- }
307
- async loadGotModule() {
308
- if (!this.gotModulePromise) {
309
- this.gotModulePromise = loadOptionalGotModule().catch((error) => {
310
- this.gotModulePromise = null;
311
- throw error;
312
- });
313
- }
314
- return this.gotModulePromise;
315
- }
316
- toGotTransferResponse(incoming) {
317
- if (!incoming || typeof incoming !== 'object') {
318
- throw new Error('invalid got response object');
319
- }
320
- const stream = incoming;
321
- const status = typeof stream.statusCode === 'number' &&
322
- Number.isFinite(stream.statusCode) &&
323
- stream.statusCode >= 100 &&
324
- stream.statusCode <= 599
325
- ? stream.statusCode
326
- : 500;
327
- const headers = {};
328
- if (stream.headers && typeof stream.headers === 'object') {
329
- const input = stream.headers;
330
- for (const key in input) {
331
- const value = input[key];
332
- if (typeof value === 'string') {
333
- headers[key] = value;
334
- continue;
335
- }
336
- if (Array.isArray(value)) {
337
- headers[key] = value.join(', ');
338
- continue;
339
- }
340
- if (value !== undefined && value !== null) {
341
- headers[key] = String(value);
171
+ const req = transport.request(url, {
172
+ method: init.method ?? 'GET',
173
+ headers: init.headers,
174
+ signal: init.signal ?? undefined,
175
+ agent: agent ?? undefined
176
+ }, (res) => {
177
+ const status = res.statusCode ?? 500;
178
+ const headers = {};
179
+ for (const key in res.headers) {
180
+ const value = res.headers[key];
181
+ if (typeof value === 'string') {
182
+ headers[key] = value;
183
+ }
184
+ else if (Array.isArray(value)) {
185
+ headers[key] = value.join(', ');
186
+ }
342
187
  }
188
+ resolve({
189
+ status,
190
+ ok: status >= 200 && status < 300,
191
+ headers,
192
+ body: res,
193
+ cancel: async () => {
194
+ res.destroy();
195
+ }
196
+ });
197
+ });
198
+ req.on('error', (error) => reject(toError(error)));
199
+ const body = init.body;
200
+ if (body instanceof Uint8Array) {
201
+ req.end(body);
343
202
  }
344
- }
345
- return {
346
- status,
347
- ok: status >= 200 && status < 300,
348
- headers,
349
- body: stream,
350
- cancel: async () => {
351
- stream.destroy();
203
+ else if (body) {
204
+ body.on('error', (err) => req.destroy(toError(err)));
205
+ body.pipe(req);
352
206
  }
353
- };
207
+ else {
208
+ req.end();
209
+ }
210
+ });
354
211
  }
355
212
  resolveTransferRequest(request, extraHeaders) {
356
213
  const headers = { ...this.defaultHeaders };
@@ -10,6 +10,8 @@ export const ENC_KEY_END = 48;
10
10
  export const MAC_KEY_START = 48;
11
11
  export const MAC_KEY_END = 80;
12
12
  export const HMAC_TRUNCATED_SIZE = 10;
13
+ export const SIDECAR_CHUNK_SIZE = 65536;
14
+ export const SIDECAR_HMAC_SIZE = 10;
13
15
  export const MEDIA_UPLOAD_PATHS = Object.freeze({
14
16
  image: '/mms/image',
15
17
  video: '/mms/video',
@@ -0,0 +1 @@
1
+ export {};
@@ -1,6 +1,8 @@
1
- import { aesGcmDecrypt, aesGcmEncrypt, importAesGcmKey } from '../crypto/index.js';
2
- import { assertMessageSecret, createUseCaseSecret, WA_USE_CASE_SECRET_MODIFICATION_TYPES } from './use-case-secret.js';
3
- import { EMPTY_BYTES, TEXT_ENCODER, toBytesView } from '../util/bytes.js';
1
+ import { aesGcmDecrypt, aesGcmEncrypt, importAesGcmKey, sha256 } from '../crypto/index.js';
2
+ import { unwrapMessage } from './content.js';
3
+ import { assertMessageSecret, createUseCaseSecret, WA_MESSAGE_SECRET_BYTES, WA_USE_CASE_SECRET_MODIFICATION_TYPES } from './use-case-secret.js';
4
+ import { proto } from '../proto.js';
5
+ import { bytesToHex, EMPTY_BYTES, TEXT_ENCODER, toBytesView } from '../util/bytes.js';
4
6
  const WA_ADDON_ENCRYPTION_NONCE_BYTES = 12;
5
7
  export function shouldUseAddonAdditionalData(modificationType) {
6
8
  return (modificationType === WA_USE_CASE_SECRET_MODIFICATION_TYPES.POLL_VOTE ||
@@ -41,6 +43,131 @@ export async function decryptAddonPayload(input) {
41
43
  const additionalData = resolveAddonAdditionalData(input);
42
44
  return aesGcmDecrypt(key, iv, toBytesView(input.ciphertext), additionalData);
43
45
  }
46
+ export function identifyEncryptedAddon(message) {
47
+ const msg = unwrapMessage(message);
48
+ if (msg.encReactionMessage) {
49
+ const { targetMessageKey, encPayload, encIv } = msg.encReactionMessage;
50
+ if (targetMessageKey && encPayload && encIv) {
51
+ return {
52
+ kind: 'reaction',
53
+ targetMessageKey,
54
+ encPayload: encPayload,
55
+ encIv: encIv,
56
+ modificationType: WA_USE_CASE_SECRET_MODIFICATION_TYPES.ENC_REACTION,
57
+ raw: message
58
+ };
59
+ }
60
+ }
61
+ if (msg.pollUpdateMessage) {
62
+ const { pollCreationMessageKey, vote } = msg.pollUpdateMessage;
63
+ if (pollCreationMessageKey && vote?.encPayload && vote.encIv) {
64
+ return {
65
+ kind: 'poll_vote',
66
+ targetMessageKey: pollCreationMessageKey,
67
+ encPayload: vote.encPayload,
68
+ encIv: vote.encIv,
69
+ modificationType: WA_USE_CASE_SECRET_MODIFICATION_TYPES.POLL_VOTE,
70
+ raw: message
71
+ };
72
+ }
73
+ }
74
+ if (msg.encEventResponseMessage) {
75
+ const { eventCreationMessageKey, encPayload, encIv } = msg.encEventResponseMessage;
76
+ if (eventCreationMessageKey && encPayload && encIv) {
77
+ return {
78
+ kind: 'event_response',
79
+ targetMessageKey: eventCreationMessageKey,
80
+ encPayload: encPayload,
81
+ encIv: encIv,
82
+ modificationType: WA_USE_CASE_SECRET_MODIFICATION_TYPES.EVENT_RESPONSE,
83
+ raw: message
84
+ };
85
+ }
86
+ }
87
+ if (msg.encCommentMessage) {
88
+ const { targetMessageKey, encPayload, encIv } = msg.encCommentMessage;
89
+ if (targetMessageKey && encPayload && encIv) {
90
+ return {
91
+ kind: 'comment',
92
+ targetMessageKey,
93
+ encPayload: encPayload,
94
+ encIv: encIv,
95
+ modificationType: WA_USE_CASE_SECRET_MODIFICATION_TYPES.ENC_COMMENT,
96
+ raw: message
97
+ };
98
+ }
99
+ }
100
+ return null;
101
+ }
102
+ export function decodeAddonPlaintext(kind, plaintext) {
103
+ switch (kind) {
104
+ case 'reaction':
105
+ return { kind, reaction: proto.Message.ReactionMessage.decode(plaintext) };
106
+ case 'poll_vote':
107
+ return {
108
+ kind,
109
+ pollVote: proto.Message.PollVoteMessage.decode(plaintext),
110
+ selectedOptionNames: null
111
+ };
112
+ case 'event_response':
113
+ return { kind, eventResponse: proto.Message.EventResponseMessage.decode(plaintext) };
114
+ case 'comment':
115
+ return { kind, comment: proto.Message.CommentMessage.decode(plaintext) };
116
+ }
117
+ }
118
+ export async function resolveParentMessageSecret(targetMessageId, messageSecretStore, messageStore) {
119
+ const cached = await messageSecretStore.get(targetMessageId);
120
+ if (cached)
121
+ return cached;
122
+ const record = await messageStore.getById(targetMessageId);
123
+ if (!record?.messageBytes)
124
+ return null;
125
+ try {
126
+ const decoded = proto.Message.decode(record.messageBytes);
127
+ const secret = decoded.messageContextInfo?.messageSecret;
128
+ if (!secret || secret.byteLength !== WA_MESSAGE_SECRET_BYTES)
129
+ return null;
130
+ return { secret, senderJid: record.senderJid ?? '' };
131
+ }
132
+ catch {
133
+ return null;
134
+ }
135
+ }
136
+ export async function resolvePollOptionNames(selectedOptions, pollCreationMessageId, messageStore) {
137
+ const record = await messageStore.getById(pollCreationMessageId);
138
+ if (!record?.messageBytes)
139
+ return null;
140
+ let decoded;
141
+ try {
142
+ decoded = proto.Message.decode(record.messageBytes);
143
+ }
144
+ catch {
145
+ return null;
146
+ }
147
+ const pollMsg = unwrapMessage(decoded);
148
+ const options = pollMsg.pollCreationMessage?.options ??
149
+ pollMsg.pollCreationMessageV2?.options ??
150
+ pollMsg.pollCreationMessageV3?.options ??
151
+ pollMsg.pollCreationMessageV5?.options;
152
+ if (!options || options.length === 0)
153
+ return null;
154
+ const hashToName = new Map();
155
+ for (const option of options) {
156
+ if (!option.optionName)
157
+ continue;
158
+ const hash = await sha256(TEXT_ENCODER.encode(option.optionName));
159
+ hashToName.set(bytesToHex(hash), option.optionName);
160
+ }
161
+ const names = [];
162
+ for (const selected of selectedOptions) {
163
+ const hex = bytesToHex(selected);
164
+ const name = hashToName.get(hex);
165
+ if (!name)
166
+ return null;
167
+ names.push(name);
168
+ }
169
+ return names;
170
+ }
44
171
  function assertAddonIv(iv) {
45
172
  const normalized = toBytesView(iv);
46
173
  if (normalized.byteLength !== WA_ADDON_ENCRYPTION_NONCE_BYTES) {
@@ -1,13 +1,9 @@
1
1
  import { proto } from '../proto.js';
2
2
  import { WA_EDIT_ATTRS, WA_ENC_MEDIA_TYPES, WA_EVENT_META_TYPES, WA_POLL_META_TYPES, WA_STANZA_MSG_TYPES } from '../protocol/constants.js';
3
3
  export function isSendMediaMessage(content) {
4
- return (!!content &&
5
- typeof content === 'object' &&
6
- 'type' in content &&
7
- 'media' in content &&
8
- 'mimetype' in content);
4
+ return !!content && typeof content === 'object' && 'type' in content && 'media' in content;
9
5
  }
10
- function unwrapMessage(message) {
6
+ export function unwrapMessage(message) {
11
7
  let msg = message;
12
8
  for (;;) {
13
9
  const inner = msg.ephemeralMessage?.message ??
@@ -70,6 +66,16 @@ export function resolveMessageTypeAttr(message) {
70
66
  return WA_STANZA_MSG_TYPES.MEDIA;
71
67
  }
72
68
  const REVOKED_REACTION_TEXT = '';
69
+ export function needsSecretPersistence(message) {
70
+ const msg = unwrapMessage(message);
71
+ return !!(msg.pollCreationMessage ||
72
+ msg.pollCreationMessageV2 ||
73
+ msg.pollCreationMessageV3 ||
74
+ msg.pollCreationMessageV4 ||
75
+ msg.pollCreationMessageV5 ||
76
+ msg.pollCreationMessageV6 ||
77
+ msg.eventMessage);
78
+ }
73
79
  export function resolveEditAttr(message, subtype) {
74
80
  const msg = unwrapMessage(message);
75
81
  if (msg.protocolMessage) {
@@ -1,13 +1,13 @@
1
1
  import { sha256, toRawPubKey } from '../crypto/index.js';
2
2
  import { parseSignalAddressFromJid } from '../protocol/jid.js';
3
3
  import { concatBytes } from '../util/bytes.js';
4
- const ICDC_HASH_LENGTH = 8;
4
+ const ICDC_DEFAULT_HASH_LENGTH = 8;
5
5
  const ICDC_FRESHNESS_THRESHOLD_MS = 30 * 24 * 60 * 60 * 1000;
6
6
  const DEVICE_LIST_METADATA_VERSION = 2;
7
- const EMPTY_KEY_HASH = new Uint8Array(ICDC_HASH_LENGTH);
8
- export async function computeDeviceKeyHash(identityKeys) {
7
+ export async function computeDeviceKeyHash(identityKeys, hashLength) {
8
+ const length = hashLength ?? ICDC_DEFAULT_HASH_LENGTH;
9
9
  if (identityKeys.length === 0) {
10
- return EMPTY_KEY_HASH;
10
+ return new Uint8Array(length);
11
11
  }
12
12
  const rawKeys = new Array(identityKeys.length);
13
13
  for (let i = 0; i < identityKeys.length; i += 1) {
@@ -16,9 +16,9 @@ export async function computeDeviceKeyHash(identityKeys) {
16
16
  }
17
17
  const combined = concatBytes(rawKeys);
18
18
  const hash = await sha256(combined);
19
- return hash.subarray(0, ICDC_HASH_LENGTH);
19
+ return hash.subarray(0, length);
20
20
  }
21
- export async function resolveIcdcMeta(deviceJids, signalStore, updatedAtMs, localIdentity) {
21
+ export async function resolveIcdcMeta(deviceJids, identityStore, updatedAtMs, localIdentity, hashLength) {
22
22
  if (deviceJids.length === 0) {
23
23
  return null;
24
24
  }
@@ -26,7 +26,7 @@ export async function resolveIcdcMeta(deviceJids, signalStore, updatedAtMs, loca
26
26
  for (let i = 0; i < deviceJids.length; i += 1) {
27
27
  addresses[i] = parseSignalAddressFromJid(deviceJids[i]);
28
28
  }
29
- const remoteKeys = await signalStore.getRemoteIdentities(addresses);
29
+ const remoteKeys = await identityStore.getRemoteIdentities(addresses);
30
30
  const keys = [];
31
31
  for (let i = 0; i < addresses.length; i += 1) {
32
32
  const key = remoteKeys[i];
@@ -42,7 +42,7 @@ export async function resolveIcdcMeta(deviceJids, signalStore, updatedAtMs, loca
42
42
  if (keys.length === 0) {
43
43
  return null;
44
44
  }
45
- const keyHash = await computeDeviceKeyHash(keys);
45
+ const keyHash = await computeDeviceKeyHash(keys, hashLength);
46
46
  const timestamp = updatedAtMs !== undefined && Date.now() - updatedAtMs < ICDC_FRESHNESS_THRESHOLD_MS
47
47
  ? Math.floor(updatedAtMs / 1000)
48
48
  : undefined;
@@ -48,14 +48,6 @@ function buildIncomingEventRawNode(node) {
48
48
  content: children
49
49
  };
50
50
  }
51
- function buildBaseIncomingEvent(node) {
52
- return {
53
- rawNode: buildIncomingEventRawNode(node),
54
- stanzaId: node.attrs.id,
55
- chatJid: node.attrs.from,
56
- stanzaType: node.attrs.type
57
- };
58
- }
59
51
  function pickSenderKeyDistributionPayload(message) {
60
52
  const direct = pickDirectSenderKeyDistributionPayload(message);
61
53
  if (direct) {
@@ -181,7 +173,10 @@ async function decryptAndProcessEncNode(node, encNode, encType, senderJid, optio
181
173
  if (shouldEmitIncomingMessage(message)) {
182
174
  const chatJid = node.attrs.from;
183
175
  options.emitIncomingMessage?.({
184
- ...buildBaseIncomingEvent(node),
176
+ rawNode: buildIncomingEventRawNode(node),
177
+ stanzaId: node.attrs.id,
178
+ chatJid,
179
+ stanzaType: node.attrs.type,
185
180
  timestampSeconds: parseOptionalInt(node.attrs.t),
186
181
  senderJid,
187
182
  encryptionType: encType,
@@ -202,7 +197,10 @@ async function decryptAndProcessEncNode(node, encNode, encType, senderJid, optio
202
197
  message: toError(error).message
203
198
  });
204
199
  options.emitUnhandledStanza?.({
205
- ...buildBaseIncomingEvent(node),
200
+ rawNode: buildIncomingEventRawNode(node),
201
+ stanzaId: node.attrs.id,
202
+ chatJid: node.attrs.from,
203
+ stanzaType: node.attrs.type,
206
204
  reason: `message.decrypt_failed.${encType}`
207
205
  });
208
206
  return { success: false, encType, error };
@@ -233,7 +231,10 @@ export async function handleIncomingMessageAck(node, options) {
233
231
  case 'skmsg': {
234
232
  if (!senderJid || !node.attrs.from || !options.senderKeyManager) {
235
233
  options.emitUnhandledStanza?.({
236
- ...buildBaseIncomingEvent(node),
234
+ rawNode: buildIncomingEventRawNode(node),
235
+ stanzaId: node.attrs.id,
236
+ chatJid: node.attrs.from,
237
+ stanzaType: node.attrs.type,
237
238
  reason: 'message.skmsg.missing_group_context'
238
239
  });
239
240
  continue;
@@ -275,7 +276,8 @@ export async function handleIncomingMessageAck(node, options) {
275
276
  });
276
277
  }
277
278
  if (encCount > 0 && !hasSuccessfulDecrypt && firstDecryptFailure) {
278
- shouldSendStandardReceipt = !(await sendRetryReceiptForDecryptFailure(node, options, firstDecryptFailure.error, firstDecryptFailure.encType));
279
+ await sendRetryReceiptForDecryptFailure(node, options, firstDecryptFailure.error, firstDecryptFailure.encType);
280
+ shouldSendStandardReceipt = false;
279
281
  }
280
282
  }
281
283
  const id = node.attrs.id;
@@ -1,5 +1,4 @@
1
1
  import { sha256 } from '../crypto/core/index.js';
2
- import { splitJid } from '../protocol/jid.js';
3
2
  import { bytesToBase64, TEXT_ENCODER } from '../util/bytes.js';
4
3
  export async function computePhashV2(participants) {
5
4
  if (participants.length === 0) {
@@ -13,15 +12,36 @@ export async function computePhashV2(participants) {
13
12
  return `2:${bytesToBase64(digest.subarray(0, 6))}`;
14
13
  }
15
14
  function toPhashCanonicalWid(jid) {
16
- const { user, server } = splitJid(jid);
17
- const normalizedServer = server === 'c.us' ? 's.whatsapp.net' : server;
18
- const colonIndex = user.indexOf(':');
19
- const userWithOptionalAgent = colonIndex >= 0 ? user.slice(0, colonIndex) : user;
20
- const baseUser = userWithOptionalAgent.endsWith('.0')
21
- ? userWithOptionalAgent.slice(0, userWithOptionalAgent.length - 2)
22
- : userWithOptionalAgent;
23
- const deviceRaw = colonIndex >= 0 ? user.slice(colonIndex + 1) : '0';
24
- const device = Number.parseInt(deviceRaw, 10);
25
- const normalizedDevice = Number.isSafeInteger(device) && device >= 0 ? device : 0;
26
- return `${baseUser}.0:${normalizedDevice}@${normalizedServer}`;
15
+ const atIndex = jid.indexOf('@');
16
+ if (atIndex < 1 || atIndex >= jid.length - 1)
17
+ return jid;
18
+ const colonIndex = jid.indexOf(':', 0);
19
+ const userEnd = colonIndex >= 0 && colonIndex < atIndex ? colonIndex : atIndex;
20
+ const hasZeroAgent = userEnd >= 2 && jid.charCodeAt(userEnd - 2) === 46 && jid.charCodeAt(userEnd - 1) === 48;
21
+ const baseUserEnd = hasZeroAgent ? userEnd - 2 : userEnd;
22
+ const baseUser = jid.slice(0, baseUserEnd);
23
+ let device = 0;
24
+ if (colonIndex >= 0 && colonIndex < atIndex) {
25
+ for (let i = colonIndex + 1; i < atIndex; i += 1) {
26
+ const digit = jid.charCodeAt(i) - 48;
27
+ if (digit < 0 || digit > 9) {
28
+ device = 0;
29
+ break;
30
+ }
31
+ device = device * 10 + digit;
32
+ if (device > Number.MAX_SAFE_INTEGER) {
33
+ device = 0;
34
+ break;
35
+ }
36
+ }
37
+ }
38
+ const serverStart = atIndex + 1;
39
+ const serverLen = jid.length - serverStart;
40
+ const isCUs = serverLen === 4 &&
41
+ jid.charCodeAt(serverStart) === 99 &&
42
+ jid.charCodeAt(serverStart + 1) === 46 &&
43
+ jid.charCodeAt(serverStart + 2) === 117 &&
44
+ jid.charCodeAt(serverStart + 3) === 115;
45
+ const normalizedServer = isCUs ? 's.whatsapp.net' : jid.slice(serverStart);
46
+ return `${baseUser}.0:${device}@${normalizedServer}`;
27
47
  }