zapo-js 0.1.2 → 0.2.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 (468) hide show
  1. package/README.md +12 -4
  2. package/dist/appstate/WaAppStateCrypto.js +1 -1
  3. package/dist/appstate/WaAppStateSyncClient.js +138 -93
  4. package/dist/appstate/{store/sqlite.js → encoding.js} +13 -8
  5. package/dist/appstate/index.js +8 -6
  6. package/dist/appstate/utils.js +0 -5
  7. package/dist/auth/WaAuthClient.js +36 -47
  8. package/dist/auth/flow/WaAuthCredentialsFlow.js +7 -7
  9. package/dist/auth/index.js +1 -6
  10. package/dist/auth/pairing/WaPairingCodeCrypto.js +6 -4
  11. package/dist/auth/pairing/WaPairingFlow.js +13 -3
  12. package/dist/client/WaClient.js +225 -101
  13. package/dist/client/WaClientFactory.js +294 -44
  14. package/dist/client/connection/WaConnectionManager.js +19 -10
  15. package/dist/client/coordinators/WaBusinessCoordinator.js +241 -0
  16. package/dist/client/coordinators/WaGroupCoordinator.js +11 -7
  17. package/dist/client/coordinators/WaIncomingNodeCoordinator.js +1 -0
  18. package/dist/client/coordinators/WaMessageDispatchCoordinator.js +292 -99
  19. package/dist/client/coordinators/WaPassiveTasksCoordinator.js +74 -31
  20. package/dist/client/coordinators/WaPrivacyCoordinator.js +134 -0
  21. package/dist/client/coordinators/WaProfileCoordinator.js +212 -0
  22. package/dist/client/coordinators/WaRetryCoordinator.js +179 -27
  23. package/dist/client/coordinators/WaStreamControlCoordinator.js +18 -11
  24. package/dist/client/coordinators/WaTrustedContactTokenCoordinator.js +166 -0
  25. package/dist/client/dirty.js +40 -20
  26. package/dist/client/events/devices.js +72 -0
  27. package/dist/client/events/group.js +3 -11
  28. package/dist/client/events/identity.js +22 -0
  29. package/dist/client/events/privacy-token.js +39 -0
  30. package/dist/client/history-sync.js +50 -9
  31. package/dist/client/incoming.js +37 -7
  32. package/dist/client/mailbox.js +24 -23
  33. package/dist/client/messages.js +107 -31
  34. package/dist/client/messaging/fanout.js +21 -11
  35. package/dist/client/messaging/participants.js +6 -4
  36. package/dist/client/persistence/WriteBehindPersistence.js +129 -0
  37. package/dist/client/tokens/cs-token.js +50 -0
  38. package/dist/client/tokens/tc-token.js +25 -0
  39. package/dist/crypto/core/index.js +2 -2
  40. package/dist/crypto/core/keys.js +4 -4
  41. package/dist/crypto/core/nonce.js +2 -0
  42. package/dist/crypto/core/primitives.js +0 -8
  43. package/dist/crypto/core/random.js +22 -0
  44. package/dist/crypto/curves/X25519.js +25 -6
  45. package/dist/crypto/index.js +3 -0
  46. package/dist/crypto/math/constants.js +13 -36
  47. package/dist/crypto/math/edwards.js +171 -44
  48. package/dist/crypto/math/fe.js +706 -0
  49. package/dist/crypto/math/mod.js +10 -3
  50. package/dist/esm/appstate/WaAppStateCrypto.js +1 -1
  51. package/dist/esm/appstate/WaAppStateSyncClient.js +138 -93
  52. package/dist/esm/appstate/{store/sqlite.js → encoding.js} +13 -8
  53. package/dist/esm/appstate/index.js +2 -2
  54. package/dist/esm/appstate/utils.js +2 -5
  55. package/dist/esm/auth/WaAuthClient.js +36 -47
  56. package/dist/esm/auth/flow/WaAuthCredentialsFlow.js +7 -7
  57. package/dist/esm/auth/index.js +0 -2
  58. package/dist/esm/auth/pairing/WaPairingCodeCrypto.js +6 -4
  59. package/dist/esm/auth/pairing/WaPairingFlow.js +14 -4
  60. package/dist/esm/client/WaClient.js +225 -101
  61. package/dist/esm/client/WaClientFactory.js +295 -45
  62. package/dist/esm/client/connection/WaConnectionManager.js +19 -10
  63. package/dist/esm/client/coordinators/WaBusinessCoordinator.js +238 -0
  64. package/dist/esm/client/coordinators/WaGroupCoordinator.js +11 -7
  65. package/dist/esm/client/coordinators/WaIncomingNodeCoordinator.js +1 -0
  66. package/dist/esm/client/coordinators/WaMessageDispatchCoordinator.js +295 -102
  67. package/dist/esm/client/coordinators/WaPassiveTasksCoordinator.js +74 -31
  68. package/dist/esm/client/coordinators/WaPrivacyCoordinator.js +131 -0
  69. package/dist/esm/client/coordinators/WaProfileCoordinator.js +209 -0
  70. package/dist/esm/client/coordinators/WaRetryCoordinator.js +181 -29
  71. package/dist/esm/client/coordinators/WaStreamControlCoordinator.js +19 -12
  72. package/dist/esm/client/coordinators/WaTrustedContactTokenCoordinator.js +162 -0
  73. package/dist/esm/client/dirty.js +40 -20
  74. package/dist/esm/client/events/devices.js +68 -0
  75. package/dist/esm/client/events/group.js +3 -11
  76. package/dist/esm/client/events/identity.js +19 -0
  77. package/dist/esm/client/events/privacy-token.js +36 -0
  78. package/dist/esm/client/history-sync.js +50 -9
  79. package/dist/esm/client/incoming.js +38 -8
  80. package/dist/esm/client/mailbox.js +24 -23
  81. package/dist/esm/client/messages.js +108 -32
  82. package/dist/esm/client/messaging/fanout.js +22 -12
  83. package/dist/esm/client/messaging/participants.js +6 -4
  84. package/dist/esm/client/persistence/WriteBehindPersistence.js +125 -0
  85. package/dist/esm/client/tokens/cs-token.js +46 -0
  86. package/dist/esm/client/tokens/tc-token.js +18 -0
  87. package/dist/esm/crypto/core/index.js +2 -2
  88. package/dist/esm/crypto/core/keys.js +1 -1
  89. package/dist/esm/crypto/core/nonce.js +2 -0
  90. package/dist/esm/crypto/core/primitives.js +0 -7
  91. package/dist/esm/crypto/core/random.js +22 -1
  92. package/dist/esm/crypto/curves/X25519.js +25 -6
  93. package/dist/esm/crypto/index.js +1 -0
  94. package/dist/esm/crypto/math/constants.js +12 -35
  95. package/dist/esm/crypto/math/edwards.js +174 -47
  96. package/dist/esm/crypto/math/fe.js +691 -0
  97. package/dist/esm/crypto/math/mod.js +10 -1
  98. package/dist/esm/index.js +1 -1
  99. package/dist/esm/infra/perf/BackgroundQueue.js +478 -0
  100. package/dist/esm/infra/perf/BoundedTaskQueue.js +3 -1
  101. package/dist/esm/infra/perf/PromiseDedup.js +20 -0
  102. package/dist/esm/infra/perf/SharedExclusiveGate.js +109 -0
  103. package/dist/esm/infra/perf/StoreLock.js +77 -0
  104. package/dist/esm/media/WaMediaCrypto.js +95 -13
  105. package/dist/esm/media/WaMediaTransferClient.js +39 -47
  106. package/dist/esm/media/constants.js +2 -1
  107. package/dist/esm/message/WaMessageClient.js +26 -19
  108. package/dist/esm/message/content.js +195 -9
  109. package/dist/esm/message/icdc.js +76 -0
  110. package/dist/esm/message/incoming.js +24 -12
  111. package/dist/esm/message/phash.js +3 -1
  112. package/dist/esm/message/reporting-token.js +14 -27
  113. package/dist/esm/protocol/appstate.js +9 -40
  114. package/dist/esm/protocol/browser.js +10 -18
  115. package/dist/esm/protocol/constants.js +5 -3
  116. package/dist/esm/protocol/defaults.js +6 -0
  117. package/dist/esm/protocol/index.js +1 -2
  118. package/dist/esm/protocol/jid.js +105 -36
  119. package/dist/esm/protocol/message.js +61 -1
  120. package/dist/esm/protocol/nodes.js +2 -0
  121. package/dist/esm/protocol/notification.js +3 -1
  122. package/dist/esm/protocol/privacy-token.js +17 -0
  123. package/dist/esm/protocol/privacy.js +55 -0
  124. package/dist/esm/protocol/stream.js +26 -1
  125. package/dist/esm/retry/codec.js +216 -0
  126. package/dist/esm/retry/constants.js +1 -1
  127. package/dist/esm/retry/index.js +2 -2
  128. package/dist/esm/retry/parse.js +50 -30
  129. package/dist/esm/retry/replay.js +11 -7
  130. package/dist/esm/retry/tracker.js +50 -12
  131. package/dist/esm/signal/api/SignalDeviceSyncApi.js +49 -32
  132. package/dist/esm/signal/api/SignalDigestSyncApi.js +13 -9
  133. package/dist/esm/signal/api/SignalIdentitySyncApi.js +26 -11
  134. package/dist/esm/signal/api/SignalMissingPreKeysSyncApi.js +18 -7
  135. package/dist/esm/signal/api/SignalRotateKeyApi.js +4 -2
  136. package/dist/esm/signal/api/SignalSessionSyncApi.js +16 -7
  137. package/dist/esm/signal/api/result-map.js +10 -0
  138. package/dist/esm/signal/constants.js +0 -4
  139. package/dist/esm/signal/crypto/WaAdvSignature.js +12 -6
  140. package/dist/esm/signal/{store/sqlite.js → encoding.js} +78 -24
  141. package/dist/esm/signal/group/SenderKeyCodec.js +3 -2
  142. package/dist/esm/signal/group/SenderKeyManager.js +125 -106
  143. package/dist/esm/signal/index.js +1 -0
  144. package/dist/esm/signal/registration/keygen.js +6 -2
  145. package/dist/esm/signal/registration/utils.js +1 -0
  146. package/dist/esm/signal/session/SignalProtocol.js +150 -74
  147. package/dist/esm/signal/session/resolver.js +137 -102
  148. package/dist/esm/store/contracts/privacy-token.store.js +1 -0
  149. package/dist/esm/store/createStore.js +101 -187
  150. package/dist/esm/store/index.js +1 -10
  151. package/dist/esm/store/locks/appstate.lock.js +26 -0
  152. package/dist/esm/store/locks/auth.lock.js +15 -0
  153. package/dist/esm/store/locks/contact.lock.js +20 -0
  154. package/dist/esm/store/locks/device-list.lock.js +20 -0
  155. package/dist/esm/store/locks/message.lock.js +21 -0
  156. package/dist/esm/store/locks/participants.lock.js +20 -0
  157. package/dist/esm/store/locks/privacy-token.lock.js +18 -0
  158. package/dist/esm/store/locks/retry.lock.js +29 -0
  159. package/dist/esm/store/locks/sender-key.lock.js +52 -0
  160. package/dist/esm/store/locks/signal.lock.js +63 -0
  161. package/dist/esm/store/locks/thread.lock.js +21 -0
  162. package/dist/esm/store/noop.store.js +1 -1
  163. package/dist/esm/store/providers/memory/appstate.store.js +22 -24
  164. package/dist/esm/store/providers/memory/device-list.store.js +10 -5
  165. package/dist/esm/store/providers/memory/privacy-token.store.js +43 -0
  166. package/dist/esm/store/providers/memory/retry.store.js +77 -2
  167. package/dist/esm/store/providers/memory/sender-key.store.js +6 -1
  168. package/dist/esm/store/providers/memory/signal.store.js +36 -19
  169. package/dist/esm/transport/WaComms.js +3 -1
  170. package/dist/esm/transport/WaWebSocket.js +0 -6
  171. package/dist/esm/transport/binary/constants.js +0 -30
  172. package/dist/esm/transport/binary/decoder.js +4 -4
  173. package/dist/esm/transport/binary/encoder.js +8 -15
  174. package/dist/esm/transport/binary/index.js +0 -1
  175. package/dist/esm/transport/node/WaNodeOrchestrator.js +25 -19
  176. package/dist/esm/transport/node/builders/business.js +129 -0
  177. package/dist/esm/transport/node/builders/global.js +370 -0
  178. package/dist/esm/transport/node/builders/index.js +5 -2
  179. package/dist/esm/transport/node/builders/message.js +63 -239
  180. package/dist/esm/transport/node/builders/pairing.js +0 -24
  181. package/dist/esm/transport/node/builders/privacy-token.js +41 -0
  182. package/dist/esm/transport/node/builders/privacy.js +48 -0
  183. package/dist/esm/transport/node/builders/profile.js +70 -0
  184. package/dist/esm/transport/node/builders/retry.js +10 -22
  185. package/dist/esm/transport/node/builders/usync.js +6 -2
  186. package/dist/esm/transport/node/helpers.js +19 -1
  187. package/dist/esm/transport/node/usync.js +3 -33
  188. package/dist/esm/transport/node/xml.js +35 -14
  189. package/dist/esm/transport/noise/WaClientPayload.js +10 -10
  190. package/dist/esm/transport/noise/WaNoiseCert.js +3 -3
  191. package/dist/esm/transport/noise/WaNoiseSession.js +64 -23
  192. package/dist/esm/transport/noise/WaNoiseSocket.js +8 -4
  193. package/dist/esm/transport/stream/parse.js +8 -4
  194. package/dist/esm/util/bytes.js +22 -18
  195. package/dist/esm/util/index.js +5 -0
  196. package/dist/esm/util/primitives.js +3 -2
  197. package/dist/index.js +7 -1
  198. package/dist/infra/perf/BackgroundQueue.js +482 -0
  199. package/dist/infra/perf/BoundedTaskQueue.js +3 -1
  200. package/dist/infra/perf/PromiseDedup.js +24 -0
  201. package/dist/infra/perf/SharedExclusiveGate.js +113 -0
  202. package/dist/infra/perf/StoreLock.js +81 -0
  203. package/dist/media/WaMediaCrypto.js +94 -12
  204. package/dist/media/WaMediaTransferClient.js +39 -47
  205. package/dist/media/constants.js +2 -1
  206. package/dist/message/WaMessageClient.js +26 -19
  207. package/dist/message/content.js +198 -9
  208. package/dist/message/icdc.js +81 -0
  209. package/dist/message/incoming.js +24 -12
  210. package/dist/message/phash.js +3 -1
  211. package/dist/message/reporting-token.js +14 -28
  212. package/dist/protocol/appstate.js +10 -41
  213. package/dist/protocol/browser.js +10 -18
  214. package/dist/protocol/constants.js +21 -2
  215. package/dist/protocol/defaults.js +6 -0
  216. package/dist/protocol/index.js +8 -5
  217. package/dist/protocol/jid.js +111 -36
  218. package/dist/protocol/message.js +62 -2
  219. package/dist/protocol/nodes.js +2 -0
  220. package/dist/protocol/notification.js +3 -1
  221. package/dist/protocol/privacy-token.js +20 -0
  222. package/dist/protocol/privacy.js +58 -0
  223. package/dist/protocol/stream.js +27 -2
  224. package/dist/retry/codec.js +220 -0
  225. package/dist/retry/constants.js +1 -1
  226. package/dist/retry/index.js +5 -5
  227. package/dist/retry/parse.js +51 -30
  228. package/dist/retry/replay.js +10 -6
  229. package/dist/retry/tracker.js +50 -12
  230. package/dist/signal/api/SignalDeviceSyncApi.js +48 -31
  231. package/dist/signal/api/SignalDigestSyncApi.js +13 -9
  232. package/dist/signal/api/SignalIdentitySyncApi.js +25 -10
  233. package/dist/signal/api/SignalMissingPreKeysSyncApi.js +17 -6
  234. package/dist/signal/api/SignalRotateKeyApi.js +4 -2
  235. package/dist/signal/api/SignalSessionSyncApi.js +16 -7
  236. package/dist/signal/api/result-map.js +13 -0
  237. package/dist/signal/constants.js +1 -5
  238. package/dist/signal/crypto/WaAdvSignature.js +11 -5
  239. package/dist/signal/{store/sqlite.js → encoding.js} +79 -25
  240. package/dist/signal/group/SenderKeyCodec.js +4 -3
  241. package/dist/signal/group/SenderKeyManager.js +125 -106
  242. package/dist/signal/index.js +13 -1
  243. package/dist/signal/registration/keygen.js +6 -2
  244. package/dist/signal/registration/utils.js +1 -0
  245. package/dist/signal/session/SignalProtocol.js +150 -74
  246. package/dist/signal/session/resolver.js +135 -100
  247. package/dist/store/contracts/privacy-token.store.js +2 -0
  248. package/dist/store/createStore.js +101 -187
  249. package/dist/store/index.js +15 -33
  250. package/dist/store/locks/appstate.lock.js +29 -0
  251. package/dist/store/locks/auth.lock.js +18 -0
  252. package/dist/store/locks/contact.lock.js +23 -0
  253. package/dist/store/locks/device-list.lock.js +23 -0
  254. package/dist/store/locks/message.lock.js +24 -0
  255. package/dist/store/locks/participants.lock.js +23 -0
  256. package/dist/store/locks/privacy-token.lock.js +21 -0
  257. package/dist/store/locks/retry.lock.js +32 -0
  258. package/dist/store/locks/sender-key.lock.js +55 -0
  259. package/dist/store/locks/signal.lock.js +66 -0
  260. package/dist/store/locks/thread.lock.js +24 -0
  261. package/dist/store/noop.store.js +1 -1
  262. package/dist/store/providers/memory/appstate.store.js +22 -24
  263. package/dist/store/providers/memory/device-list.store.js +10 -5
  264. package/dist/store/providers/memory/privacy-token.store.js +47 -0
  265. package/dist/store/providers/memory/retry.store.js +77 -2
  266. package/dist/store/providers/memory/sender-key.store.js +6 -1
  267. package/dist/store/providers/memory/signal.store.js +36 -19
  268. package/dist/transport/WaComms.js +3 -1
  269. package/dist/transport/WaWebSocket.js +0 -6
  270. package/dist/transport/binary/constants.js +1 -31
  271. package/dist/transport/binary/decoder.js +4 -4
  272. package/dist/transport/binary/encoder.js +8 -15
  273. package/dist/transport/binary/index.js +0 -4
  274. package/dist/transport/node/WaNodeOrchestrator.js +24 -18
  275. package/dist/transport/node/builders/business.js +137 -0
  276. package/dist/transport/node/builders/global.js +375 -0
  277. package/dist/transport/node/builders/index.js +18 -9
  278. package/dist/transport/node/builders/message.js +64 -245
  279. package/dist/transport/node/builders/pairing.js +0 -26
  280. package/dist/transport/node/builders/privacy-token.js +46 -0
  281. package/dist/transport/node/builders/privacy.js +55 -0
  282. package/dist/transport/node/builders/profile.js +78 -0
  283. package/dist/transport/node/builders/retry.js +9 -21
  284. package/dist/transport/node/builders/usync.js +6 -2
  285. package/dist/transport/node/helpers.js +20 -1
  286. package/dist/transport/node/usync.js +2 -32
  287. package/dist/transport/node/xml.js +35 -14
  288. package/dist/transport/noise/WaClientPayload.js +13 -13
  289. package/dist/transport/noise/WaNoiseCert.js +2 -2
  290. package/dist/transport/noise/WaNoiseSession.js +64 -23
  291. package/dist/transport/noise/WaNoiseSocket.js +8 -4
  292. package/dist/transport/stream/parse.js +7 -3
  293. package/dist/types/appstate/encoding.d.ts +7 -0
  294. package/dist/types/appstate/index.d.ts +3 -3
  295. package/dist/types/appstate/utils.d.ts +0 -2
  296. package/dist/types/auth/flow/WaAuthCredentialsFlow.d.ts +1 -1
  297. package/dist/types/auth/index.d.ts +0 -2
  298. package/dist/types/auth/types.d.ts +1 -0
  299. package/dist/types/client/WaClient.d.ts +27 -12
  300. package/dist/types/client/WaClientFactory.d.ts +12 -4
  301. package/dist/types/client/connection/WaConnectionManager.d.ts +2 -0
  302. package/dist/types/client/coordinators/WaBusinessCoordinator.d.ts +57 -0
  303. package/dist/types/client/coordinators/WaIncomingNodeCoordinator.d.ts +3 -1
  304. package/dist/types/client/coordinators/WaMessageDispatchCoordinator.d.ts +14 -0
  305. package/dist/types/client/coordinators/WaPassiveTasksCoordinator.d.ts +4 -0
  306. package/dist/types/client/coordinators/WaPrivacyCoordinator.d.ts +26 -0
  307. package/dist/types/client/coordinators/WaProfileCoordinator.d.ts +36 -0
  308. package/dist/types/client/coordinators/WaRetryCoordinator.d.ts +6 -0
  309. package/dist/types/client/coordinators/WaStreamControlCoordinator.d.ts +3 -2
  310. package/dist/types/client/coordinators/WaTrustedContactTokenCoordinator.d.ts +45 -0
  311. package/dist/types/client/events/devices.d.ts +20 -0
  312. package/dist/types/client/events/identity.d.ts +9 -0
  313. package/dist/types/client/events/privacy-token.d.ts +7 -0
  314. package/dist/types/client/history-sync.d.ts +9 -6
  315. package/dist/types/client/incoming.d.ts +3 -1
  316. package/dist/types/client/index.d.ts +1 -1
  317. package/dist/types/client/mailbox.d.ts +3 -5
  318. package/dist/types/client/messages.d.ts +1 -2
  319. package/dist/types/client/persistence/WriteBehindPersistence.d.ts +34 -0
  320. package/dist/types/client/tokens/cs-token.d.ts +10 -0
  321. package/dist/types/client/tokens/tc-token.d.ts +5 -0
  322. package/dist/types/client/types.d.ts +51 -3
  323. package/dist/types/crypto/core/index.d.ts +2 -2
  324. package/dist/types/crypto/core/nonce.d.ts +2 -0
  325. package/dist/types/crypto/core/primitives.d.ts +0 -1
  326. package/dist/types/crypto/core/random.d.ts +1 -0
  327. package/dist/types/crypto/index.d.ts +1 -0
  328. package/dist/types/crypto/math/constants.d.ts +4 -2
  329. package/dist/types/crypto/math/fe.d.ts +30 -0
  330. package/dist/types/crypto/math/mod.d.ts +0 -2
  331. package/dist/types/crypto/math/types.d.ts +11 -4
  332. package/dist/types/index.d.ts +5 -3
  333. package/dist/types/infra/perf/BackgroundQueue.d.ts +58 -0
  334. package/dist/types/infra/perf/PromiseDedup.d.ts +4 -0
  335. package/dist/types/infra/perf/SharedExclusiveGate.d.ts +17 -0
  336. package/dist/types/infra/perf/StoreLock.d.ts +10 -0
  337. package/dist/types/media/WaMediaCrypto.d.ts +3 -2
  338. package/dist/types/media/WaMediaTransferClient.d.ts +3 -12
  339. package/dist/types/media/constants.d.ts +1 -1
  340. package/dist/types/media/index.d.ts +1 -1
  341. package/dist/types/media/types.d.ts +10 -2
  342. package/dist/types/message/content.d.ts +8 -0
  343. package/dist/types/message/icdc.d.ts +13 -0
  344. package/dist/types/message/reporting-token.d.ts +0 -1
  345. package/dist/types/message/types.d.ts +45 -6
  346. package/dist/types/protocol/appstate.d.ts +0 -11
  347. package/dist/types/protocol/constants.d.ts +7 -3
  348. package/dist/types/protocol/defaults.d.ts +6 -0
  349. package/dist/types/protocol/index.d.ts +1 -2
  350. package/dist/types/protocol/jid.d.ts +19 -2
  351. package/dist/types/protocol/message.d.ts +60 -0
  352. package/dist/types/protocol/nodes.d.ts +2 -0
  353. package/dist/types/protocol/notification.d.ts +2 -0
  354. package/dist/types/protocol/privacy-token.d.ts +17 -0
  355. package/dist/types/protocol/privacy.d.ts +75 -0
  356. package/dist/types/protocol/stream.d.ts +30 -0
  357. package/dist/types/retry/codec.d.ts +3 -0
  358. package/dist/types/retry/index.d.ts +3 -3
  359. package/dist/types/retry/parse.d.ts +5 -2
  360. package/dist/types/retry/tracker.d.ts +1 -0
  361. package/dist/types/retry/types.d.ts +6 -1
  362. package/dist/types/signal/api/SignalDeviceSyncApi.d.ts +2 -1
  363. package/dist/types/signal/api/SignalDigestSyncApi.d.ts +6 -0
  364. package/dist/types/signal/api/SignalIdentitySyncApi.d.ts +2 -0
  365. package/dist/types/signal/api/SignalRotateKeyApi.d.ts +4 -5
  366. package/dist/types/signal/api/SignalSessionSyncApi.d.ts +8 -6
  367. package/dist/types/signal/api/result-map.d.ts +1 -0
  368. package/dist/types/signal/constants.d.ts +0 -3
  369. package/dist/types/signal/{store/sqlite.d.ts → encoding.d.ts} +3 -3
  370. package/dist/types/signal/group/SenderKeyManager.d.ts +10 -5
  371. package/dist/types/signal/index.d.ts +2 -0
  372. package/dist/types/signal/session/SignalProtocol.d.ts +10 -4
  373. package/dist/types/signal/session/resolver.d.ts +7 -2
  374. package/dist/types/store/contracts/appstate.store.d.ts +1 -1
  375. package/dist/types/store/contracts/privacy-token.store.d.ts +16 -0
  376. package/dist/types/store/contracts/retry.store.d.ts +7 -0
  377. package/dist/types/store/contracts/signal.store.d.ts +7 -0
  378. package/dist/types/store/createStore.d.ts +1 -1
  379. package/dist/types/store/index.d.ts +5 -13
  380. package/dist/types/store/locks/appstate.lock.d.ts +3 -0
  381. package/dist/types/store/locks/auth.lock.d.ts +3 -0
  382. package/dist/types/store/locks/contact.lock.d.ts +3 -0
  383. package/dist/types/store/locks/device-list.lock.d.ts +2 -0
  384. package/dist/types/store/locks/message.lock.d.ts +3 -0
  385. package/dist/types/store/locks/participants.lock.d.ts +2 -0
  386. package/dist/types/store/locks/privacy-token.lock.d.ts +2 -0
  387. package/dist/types/store/locks/retry.lock.d.ts +2 -0
  388. package/dist/types/store/locks/sender-key.lock.d.ts +3 -0
  389. package/dist/types/store/locks/signal.lock.d.ts +3 -0
  390. package/dist/types/store/locks/thread.lock.d.ts +3 -0
  391. package/dist/types/store/providers/memory/appstate.store.d.ts +1 -1
  392. package/dist/types/store/providers/memory/privacy-token.store.d.ts +13 -0
  393. package/dist/types/store/providers/memory/retry.store.d.ts +8 -0
  394. package/dist/types/store/providers/memory/signal.store.d.ts +2 -1
  395. package/dist/types/store/types.d.ts +49 -61
  396. package/dist/types/transport/WaWebSocket.d.ts +0 -1
  397. package/dist/types/transport/binary/constants.d.ts +0 -30
  398. package/dist/types/transport/binary/index.d.ts +0 -1
  399. package/dist/types/transport/node/WaNodeOrchestrator.d.ts +3 -4
  400. package/dist/types/transport/node/builders/business.d.ts +29 -0
  401. package/dist/types/transport/node/builders/global.d.ts +102 -0
  402. package/dist/types/transport/node/builders/index.d.ts +5 -2
  403. package/dist/types/transport/node/builders/message.d.ts +8 -7
  404. package/dist/types/transport/node/builders/pairing.d.ts +0 -2
  405. package/dist/types/transport/node/builders/privacy-token.d.ts +9 -0
  406. package/dist/types/transport/node/builders/privacy.d.ts +7 -0
  407. package/dist/types/transport/node/builders/profile.d.ts +8 -0
  408. package/dist/types/transport/node/builders/retry.d.ts +0 -1
  409. package/dist/types/transport/node/helpers.d.ts +5 -0
  410. package/dist/types/transport/noise/WaNoiseSession.d.ts +3 -2
  411. package/dist/types/transport/noise/WaNoiseSocket.d.ts +4 -2
  412. package/dist/types/util/bytes.d.ts +1 -1
  413. package/dist/types/util/index.d.ts +5 -0
  414. package/dist/types/util/primitives.d.ts +0 -1
  415. package/dist/util/bytes.js +22 -18
  416. package/dist/util/index.js +23 -0
  417. package/dist/util/primitives.js +2 -2
  418. package/package.json +29 -7
  419. package/proto/index.js +1 -1
  420. package/dist/crypto/core/constants.js +0 -4
  421. package/dist/esm/crypto/core/constants.js +0 -1
  422. package/dist/esm/retry/outbound.js +0 -82
  423. package/dist/esm/store/providers/sqlite/BaseSqliteStore.js +0 -37
  424. package/dist/esm/store/providers/sqlite/appstate.store.js +0 -250
  425. package/dist/esm/store/providers/sqlite/auth.store.js +0 -176
  426. package/dist/esm/store/providers/sqlite/connection.js +0 -245
  427. package/dist/esm/store/providers/sqlite/contact.store.js +0 -74
  428. package/dist/esm/store/providers/sqlite/device-list.store.js +0 -127
  429. package/dist/esm/store/providers/sqlite/message.store.js +0 -132
  430. package/dist/esm/store/providers/sqlite/migrations.js +0 -347
  431. package/dist/esm/store/providers/sqlite/participants.store.js +0 -77
  432. package/dist/esm/store/providers/sqlite/retry.store.js +0 -141
  433. package/dist/esm/store/providers/sqlite/sender-key.store.js +0 -198
  434. package/dist/esm/store/providers/sqlite/signal.store.js +0 -435
  435. package/dist/esm/store/providers/sqlite/table-names.js +0 -107
  436. package/dist/esm/store/providers/sqlite/thread.store.js +0 -85
  437. package/dist/retry/outbound.js +0 -87
  438. package/dist/store/providers/sqlite/BaseSqliteStore.js +0 -41
  439. package/dist/store/providers/sqlite/appstate.store.js +0 -254
  440. package/dist/store/providers/sqlite/auth.store.js +0 -180
  441. package/dist/store/providers/sqlite/connection.js +0 -281
  442. package/dist/store/providers/sqlite/contact.store.js +0 -78
  443. package/dist/store/providers/sqlite/device-list.store.js +0 -131
  444. package/dist/store/providers/sqlite/message.store.js +0 -136
  445. package/dist/store/providers/sqlite/migrations.js +0 -350
  446. package/dist/store/providers/sqlite/participants.store.js +0 -81
  447. package/dist/store/providers/sqlite/retry.store.js +0 -145
  448. package/dist/store/providers/sqlite/sender-key.store.js +0 -202
  449. package/dist/store/providers/sqlite/signal.store.js +0 -439
  450. package/dist/store/providers/sqlite/table-names.js +0 -113
  451. package/dist/store/providers/sqlite/thread.store.js +0 -89
  452. package/dist/types/appstate/store/sqlite.d.ts +0 -7
  453. package/dist/types/crypto/core/constants.d.ts +0 -1
  454. package/dist/types/retry/outbound.d.ts +0 -4
  455. package/dist/types/store/providers/sqlite/BaseSqliteStore.d.ts +0 -12
  456. package/dist/types/store/providers/sqlite/appstate.store.d.ts +0 -17
  457. package/dist/types/store/providers/sqlite/auth.store.d.ts +0 -10
  458. package/dist/types/store/providers/sqlite/connection.d.ts +0 -10
  459. package/dist/types/store/providers/sqlite/contact.store.d.ts +0 -12
  460. package/dist/types/store/providers/sqlite/device-list.store.d.ts +0 -15
  461. package/dist/types/store/providers/sqlite/message.store.d.ts +0 -13
  462. package/dist/types/store/providers/sqlite/migrations.d.ts +0 -3
  463. package/dist/types/store/providers/sqlite/participants.store.d.ts +0 -12
  464. package/dist/types/store/providers/sqlite/retry.store.d.ts +0 -15
  465. package/dist/types/store/providers/sqlite/sender-key.store.d.ts +0 -24
  466. package/dist/types/store/providers/sqlite/signal.store.d.ts +0 -53
  467. package/dist/types/store/providers/sqlite/table-names.d.ts +0 -5
  468. package/dist/types/store/providers/sqlite/thread.store.d.ts +0 -13
@@ -0,0 +1,76 @@
1
+ import { sha256, toRawPubKey } from '../crypto/index.js';
2
+ import { parseSignalAddressFromJid } from '../protocol/jid.js';
3
+ import { concatBytes } from '../util/bytes.js';
4
+ const ICDC_HASH_LENGTH = 8;
5
+ const ICDC_FRESHNESS_THRESHOLD_MS = 30 * 24 * 60 * 60 * 1000;
6
+ const DEVICE_LIST_METADATA_VERSION = 2;
7
+ const EMPTY_KEY_HASH = new Uint8Array(ICDC_HASH_LENGTH);
8
+ export async function computeDeviceKeyHash(identityKeys) {
9
+ if (identityKeys.length === 0) {
10
+ return EMPTY_KEY_HASH;
11
+ }
12
+ const rawKeys = new Array(identityKeys.length);
13
+ for (let i = 0; i < identityKeys.length; i += 1) {
14
+ rawKeys[i] =
15
+ identityKeys[i].byteLength === 33 ? toRawPubKey(identityKeys[i]) : identityKeys[i];
16
+ }
17
+ const combined = concatBytes(rawKeys);
18
+ const hash = await sha256(combined);
19
+ return hash.subarray(0, ICDC_HASH_LENGTH);
20
+ }
21
+ export async function resolveIcdcMeta(deviceJids, signalStore, updatedAtMs, localIdentity) {
22
+ if (deviceJids.length === 0) {
23
+ return null;
24
+ }
25
+ const addresses = new Array(deviceJids.length);
26
+ for (let i = 0; i < deviceJids.length; i += 1) {
27
+ addresses[i] = parseSignalAddressFromJid(deviceJids[i]);
28
+ }
29
+ const remoteKeys = await signalStore.getRemoteIdentities(addresses);
30
+ const keys = [];
31
+ for (let i = 0; i < addresses.length; i += 1) {
32
+ const key = remoteKeys[i];
33
+ if (key) {
34
+ keys.push(key);
35
+ }
36
+ else if (localIdentity &&
37
+ addresses[i].user === localIdentity.address.user &&
38
+ addresses[i].device === localIdentity.address.device) {
39
+ keys.push(localIdentity.pubKey);
40
+ }
41
+ }
42
+ if (keys.length === 0) {
43
+ return null;
44
+ }
45
+ const keyHash = await computeDeviceKeyHash(keys);
46
+ const timestamp = updatedAtMs !== undefined && Date.now() - updatedAtMs < ICDC_FRESHNESS_THRESHOLD_MS
47
+ ? Math.floor(updatedAtMs / 1000)
48
+ : undefined;
49
+ return { keyHash, timestamp };
50
+ }
51
+ export function injectDeviceListMetadata(message, senderIcdc, recipientIcdc) {
52
+ if (!senderIcdc && !recipientIcdc) {
53
+ return message;
54
+ }
55
+ const deviceListMetadata = {};
56
+ if (senderIcdc) {
57
+ deviceListMetadata.senderKeyHash = senderIcdc.keyHash;
58
+ if (senderIcdc.timestamp !== undefined) {
59
+ deviceListMetadata.senderTimestamp = senderIcdc.timestamp;
60
+ }
61
+ }
62
+ if (recipientIcdc) {
63
+ deviceListMetadata.recipientKeyHash = recipientIcdc.keyHash;
64
+ if (recipientIcdc.timestamp !== undefined) {
65
+ deviceListMetadata.recipientTimestamp = recipientIcdc.timestamp;
66
+ }
67
+ }
68
+ return {
69
+ ...message,
70
+ messageContextInfo: {
71
+ ...message.messageContextInfo,
72
+ deviceListMetadata,
73
+ deviceListMetadataVersion: DEVICE_LIST_METADATA_VERSION
74
+ }
75
+ };
76
+ }
@@ -3,12 +3,9 @@ import { unpadPkcs7 } from './padding.js';
3
3
  import { proto } from '../proto.js';
4
4
  import { WA_MESSAGE_TAGS, WA_MESSAGE_TYPES } from '../protocol/constants.js';
5
5
  import { isBroadcastJid, isGroupJid, parseSignalAddressFromJid } from '../protocol/jid.js';
6
- import { buildInboundDeliveryReceiptNode, buildInboundMessageAckNode, buildInboundRetryReceiptNode } from '../transport/node/builders/message.js';
6
+ import { buildAckNode, buildReceiptNode } from '../transport/node/builders/global.js';
7
7
  import { decodeNodeContentBase64OrBytes, findNodeChild } from '../transport/node/helpers.js';
8
8
  import { parseOptionalInt, toError } from '../util/primitives.js';
9
- function parseMessageTimestamp(value) {
10
- return parseOptionalInt(value);
11
- }
12
9
  function pickNextRetryCount(node) {
13
10
  const retryNode = findNodeChild(node, 'retry');
14
11
  const parsed = parseOptionalInt(retryNode?.attrs.count);
@@ -125,7 +122,13 @@ async function sendRetryReceiptForDecryptFailure(node, options, error, encType)
125
122
  if (options.onDecryptFailure) {
126
123
  return options.onDecryptFailure(retryContext, error);
127
124
  }
128
- const retryReceiptNode = buildInboundRetryReceiptNode(node, stanzaId, from, options.getMeJid?.(), pickNextRetryCount(node));
125
+ const retryReceiptNode = buildReceiptNode({
126
+ kind: 'retry',
127
+ node,
128
+ id: stanzaId,
129
+ to: from,
130
+ retryCount: pickNextRetryCount(node)
131
+ });
129
132
  try {
130
133
  await options.sendNode(retryReceiptNode);
131
134
  options.logger.debug('sent retry receipt for undecryptable incoming message', {
@@ -152,7 +155,8 @@ async function decryptAndProcessEncNode(node, encNode, encType, senderJid, optio
152
155
  const senderAddress = parseSignalAddressFromJid(senderJid);
153
156
  const decryptedPayload = await decrypt(decodeNodeContentBase64OrBytes(encNode.content, 'message.enc'), senderAddress);
154
157
  const unpaddedPlaintext = unpadPkcs7(decryptedPayload);
155
- const message = normalizeIncomingDecryptedMessage(proto.Message.decode(unpaddedPlaintext));
158
+ const decodedMessage = proto.Message.decode(unpaddedPlaintext);
159
+ const message = unwrapDeviceSentMessage(decodedMessage) ?? decodedMessage;
156
160
  const senderKeyDistribution = pickSenderKeyDistributionPayload(message);
157
161
  if (senderKeyDistribution && options.senderKeyManager) {
158
162
  try {
@@ -178,7 +182,7 @@ async function decryptAndProcessEncNode(node, encNode, encType, senderJid, optio
178
182
  const chatJid = node.attrs.from;
179
183
  options.emitIncomingMessage?.({
180
184
  ...buildBaseIncomingEvent(node),
181
- timestampSeconds: parseMessageTimestamp(node.attrs.t),
185
+ timestampSeconds: parseOptionalInt(node.attrs.t),
182
186
  senderJid,
183
187
  encryptionType: encType,
184
188
  isGroupChat: chatJid ? isGroupJid(chatJid) : false,
@@ -285,7 +289,13 @@ export async function handleIncomingMessageAck(node, options) {
285
289
  return true;
286
290
  }
287
291
  if (node.attrs.type === WA_MESSAGE_TYPES.MEDIA_NOTIFY) {
288
- const ackNode = buildInboundMessageAckNode(node, id, from, options.getMeJid?.());
292
+ const ackNode = buildAckNode({
293
+ kind: 'message',
294
+ node,
295
+ id,
296
+ to: from,
297
+ from: options.getMeJid?.()
298
+ });
289
299
  options.logger.debug('sending inbound message ack', {
290
300
  id,
291
301
  to: from,
@@ -298,7 +308,12 @@ export async function handleIncomingMessageAck(node, options) {
298
308
  if (!shouldSendStandardReceipt) {
299
309
  return true;
300
310
  }
301
- const receiptNode = buildInboundDeliveryReceiptNode(node, id, from);
311
+ const receiptNode = buildReceiptNode({
312
+ kind: 'delivery',
313
+ node,
314
+ id,
315
+ to: from
316
+ });
302
317
  options.logger.debug('sending inbound message receipt', {
303
318
  id,
304
319
  to: from,
@@ -308,6 +323,3 @@ export async function handleIncomingMessageAck(node, options) {
308
323
  await options.sendNode(receiptNode);
309
324
  return true;
310
325
  }
311
- function normalizeIncomingDecryptedMessage(message) {
312
- return unwrapDeviceSentMessage(message) ?? message;
313
- }
@@ -5,7 +5,9 @@ export async function computePhashV2(participants) {
5
5
  if (participants.length === 0) {
6
6
  return '2:';
7
7
  }
8
- const canonical = participants.map((participant) => toPhashCanonicalWid(participant));
8
+ const canonical = new Array(participants.length);
9
+ for (let i = 0; i < participants.length; i += 1)
10
+ canonical[i] = toPhashCanonicalWid(participants[i]);
9
11
  const joined = canonical.sort().join('');
10
12
  const digest = await sha256(TEXT_ENCODER.encode(joined));
11
13
  return `2:${bytesToBase64(digest.subarray(0, 6))}`;
@@ -9,10 +9,6 @@ const WA_REPORTING_TOKEN_CONFIG_BYTES = base64ToBytesChecked(WA_REPORTING_TOKEN_
9
9
  export const WA_REPORTING_TOKEN_VERSION = 2;
10
10
  let reportingTokenConfigSpec = null;
11
11
  const reportingTokenConfigCache = new Map();
12
- export async function buildReportingTokenNode(input) {
13
- const artifacts = await buildReportingTokenArtifacts(input);
14
- return artifacts?.node ?? null;
15
- }
16
12
  export async function buildReportingTokenArtifacts(input) {
17
13
  const stanzaId = input.stanzaId.trim();
18
14
  if (!stanzaId || !isMessageReportingTokenCompatible(input.message)) {
@@ -26,12 +22,7 @@ export async function buildReportingTokenArtifacts(input) {
26
22
  if (reportingTokenContent.byteLength === 0) {
27
23
  return null;
28
24
  }
29
- const secretInfo = concatBytes([
30
- TEXT_ENCODER.encode(stanzaId),
31
- TEXT_ENCODER.encode(input.senderUserJid),
32
- TEXT_ENCODER.encode(input.remoteJid),
33
- TEXT_ENCODER.encode(WA_REPORTING_TOKEN_USE_CASE)
34
- ]);
25
+ const secretInfo = TEXT_ENCODER.encode(stanzaId + input.senderUserJid + input.remoteJid + WA_REPORTING_TOKEN_USE_CASE);
35
26
  const reportingTokenKey = await hkdf(toBytesView(messageSecret), null, secretInfo, WA_REPORTING_TOKEN_KEY_BYTES);
36
27
  const hmacKey = await importHmacKey(reportingTokenKey);
37
28
  const reportingToken = (await hmacSign(hmacKey, reportingTokenContent)).subarray(0, WA_REPORTING_TOKEN_BYTES);
@@ -68,13 +59,11 @@ function computeReportingTokenContent(messageBytes, version) {
68
59
  if (extracted.totalSize === 0) {
69
60
  return EMPTY_BYTES;
70
61
  }
71
- const output = new Uint8Array(extracted.totalSize);
72
- let offset = 0;
73
- for (const part of extracted.parts) {
74
- output.set(part.bytes, offset);
75
- offset += part.bytes.length;
62
+ const parts = new Array(extracted.parts.length);
63
+ for (let index = 0; index < extracted.parts.length; index += 1) {
64
+ parts[index] = extracted.parts[index].bytes;
76
65
  }
77
- return output;
66
+ return concatBytes(parts);
78
67
  }
79
68
  function getReportingTokenConfig(version) {
80
69
  const cached = reportingTokenConfigCache.get(version);
@@ -251,7 +240,8 @@ function extractProtobufFieldParts(bytes, start, end, config, rootConfig) {
251
240
  if (!configuredField) {
252
241
  continue;
253
242
  }
254
- if (!configuredField.isMessage && isExtractWholeField(configuredField)) {
243
+ if (!configuredField.isMessage &&
244
+ (!configuredField.subfields || configuredField.subfields.fields.size === 0)) {
255
245
  const fieldBytes = bytes.subarray(parsedField.start, parsedField.next);
256
246
  parts.push({
257
247
  fieldNumber: parsedField.fieldNumber,
@@ -293,9 +283,6 @@ function extractProtobufFieldParts(bytes, start, end, config, rootConfig) {
293
283
  totalSize
294
284
  };
295
285
  }
296
- function isExtractWholeField(field) {
297
- return !field.subfields || field.subfields.fields.size === 0;
298
- }
299
286
  function parseProtobufField(bytes, start, end) {
300
287
  const tag = readVarint(bytes, start, end);
301
288
  const tagValue = tag.value;
@@ -424,15 +411,15 @@ function encodeVarint(value) {
424
411
  if (!Number.isSafeInteger(value) || value < 0) {
425
412
  throw new Error(`invalid varint value: ${value}`);
426
413
  }
427
- if (value === 0) {
428
- return new Uint8Array([0]);
429
- }
430
- const bytes = [];
414
+ const bytes = new Uint8Array(10);
415
+ let length = 0;
431
416
  let current = value;
432
417
  while (current >= 128) {
433
- bytes.push((current % 128) + 128);
418
+ bytes[length] = (current % 128) + 128;
419
+ length += 1;
434
420
  current = Math.floor(current / 128);
435
421
  }
436
- bytes.push(current);
437
- return new Uint8Array(bytes);
422
+ bytes[length] = current;
423
+ length += 1;
424
+ return bytes.subarray(0, length);
438
425
  }
@@ -32,61 +32,30 @@ export const WA_APP_STATE_KDF_INFO = Object.freeze({
32
32
  MUTATION_KEYS: 'WhatsApp Mutation Keys',
33
33
  PATCH_INTEGRITY: 'WhatsApp Patch Integrity'
34
34
  });
35
- export const WA_APP_STATE_CHAT_MUTATION_ACTIONS = Object.freeze({
36
- STAR: 'star',
37
- MUTE: 'mute',
38
- PIN: 'pin_v1',
39
- ARCHIVE: 'archive',
40
- DELETE_MESSAGE_FOR_ME: 'deleteMessageForMe',
41
- MARK_CHAT_AS_READ: 'markChatAsRead',
42
- CLEAR_CHAT: 'clearChat',
43
- DELETE_CHAT: 'deleteChat',
44
- LOCK_CHAT: 'lock'
45
- });
46
35
  export const WA_APP_STATE_CHAT_MUTATION_SPECS = Object.freeze({
47
- STAR: {
48
- collection: WA_APP_STATE_COLLECTIONS.REGULAR_HIGH,
49
- action: WA_APP_STATE_CHAT_MUTATION_ACTIONS.STAR,
50
- version: 2
51
- },
52
- MUTE: {
53
- collection: WA_APP_STATE_COLLECTIONS.REGULAR_HIGH,
54
- action: WA_APP_STATE_CHAT_MUTATION_ACTIONS.MUTE,
55
- version: 2
56
- },
57
- PIN: {
58
- collection: WA_APP_STATE_COLLECTIONS.REGULAR_LOW,
59
- action: WA_APP_STATE_CHAT_MUTATION_ACTIONS.PIN,
60
- version: 5
61
- },
62
- ARCHIVE: {
63
- collection: WA_APP_STATE_COLLECTIONS.REGULAR_LOW,
64
- action: WA_APP_STATE_CHAT_MUTATION_ACTIONS.ARCHIVE,
65
- version: 3
66
- },
36
+ STAR: { collection: WA_APP_STATE_COLLECTIONS.REGULAR_HIGH, action: 'star', version: 2 },
37
+ MUTE: { collection: WA_APP_STATE_COLLECTIONS.REGULAR_HIGH, action: 'mute', version: 2 },
38
+ PIN: { collection: WA_APP_STATE_COLLECTIONS.REGULAR_LOW, action: 'pin_v1', version: 5 },
39
+ ARCHIVE: { collection: WA_APP_STATE_COLLECTIONS.REGULAR_LOW, action: 'archive', version: 3 },
67
40
  DELETE_MESSAGE_FOR_ME: {
68
41
  collection: WA_APP_STATE_COLLECTIONS.REGULAR_HIGH,
69
- action: WA_APP_STATE_CHAT_MUTATION_ACTIONS.DELETE_MESSAGE_FOR_ME,
42
+ action: 'deleteMessageForMe',
70
43
  version: 3
71
44
  },
72
45
  MARK_CHAT_AS_READ: {
73
46
  collection: WA_APP_STATE_COLLECTIONS.REGULAR_LOW,
74
- action: WA_APP_STATE_CHAT_MUTATION_ACTIONS.MARK_CHAT_AS_READ,
47
+ action: 'markChatAsRead',
75
48
  version: 3
76
49
  },
77
50
  CLEAR_CHAT: {
78
51
  collection: WA_APP_STATE_COLLECTIONS.REGULAR_HIGH,
79
- action: WA_APP_STATE_CHAT_MUTATION_ACTIONS.CLEAR_CHAT,
52
+ action: 'clearChat',
80
53
  version: 6
81
54
  },
82
55
  DELETE_CHAT: {
83
56
  collection: WA_APP_STATE_COLLECTIONS.REGULAR_HIGH,
84
- action: WA_APP_STATE_CHAT_MUTATION_ACTIONS.DELETE_CHAT,
57
+ action: 'deleteChat',
85
58
  version: 6
86
59
  },
87
- LOCK_CHAT: {
88
- collection: WA_APP_STATE_COLLECTIONS.REGULAR_LOW,
89
- action: WA_APP_STATE_CHAT_MUTATION_ACTIONS.LOCK_CHAT,
90
- version: 7
91
- }
60
+ LOCK_CHAT: { collection: WA_APP_STATE_COLLECTIONS.REGULAR_LOW, action: 'lock', version: 7 }
92
61
  });
@@ -19,23 +19,15 @@ export const WA_COMPANION_PLATFORM_IDS = Object.freeze({
19
19
  UWP: '8',
20
20
  OTHER_WEB_CLIENT: '9'
21
21
  });
22
+ const BROWSER_TO_PLATFORM_ID = {
23
+ [WA_BROWSERS.CHROME]: WA_COMPANION_PLATFORM_IDS.CHROME,
24
+ [WA_BROWSERS.FIREFOX]: WA_COMPANION_PLATFORM_IDS.FIREFOX,
25
+ [WA_BROWSERS.IE]: WA_COMPANION_PLATFORM_IDS.IE,
26
+ [WA_BROWSERS.OPERA]: WA_COMPANION_PLATFORM_IDS.OPERA,
27
+ [WA_BROWSERS.SAFARI]: WA_COMPANION_PLATFORM_IDS.SAFARI,
28
+ [WA_BROWSERS.EDGE]: WA_COMPANION_PLATFORM_IDS.EDGE
29
+ };
22
30
  export function getWaCompanionPlatformId(browser) {
23
- const normalized = browser.trim().toLowerCase();
24
- switch (normalized) {
25
- case WA_BROWSERS.CHROME:
26
- return WA_COMPANION_PLATFORM_IDS.CHROME;
27
- case WA_BROWSERS.FIREFOX:
28
- return WA_COMPANION_PLATFORM_IDS.FIREFOX;
29
- case WA_BROWSERS.IE:
30
- return WA_COMPANION_PLATFORM_IDS.IE;
31
- case WA_BROWSERS.OPERA:
32
- return WA_COMPANION_PLATFORM_IDS.OPERA;
33
- case WA_BROWSERS.SAFARI:
34
- return WA_COMPANION_PLATFORM_IDS.SAFARI;
35
- case WA_BROWSERS.EDGE:
36
- return WA_COMPANION_PLATFORM_IDS.EDGE;
37
- case WA_BROWSERS.CHROMIUM:
38
- default:
39
- return WA_COMPANION_PLATFORM_IDS.OTHER_WEB_CLIENT;
40
- }
31
+ return (BROWSER_TO_PLATFORM_ID[browser.trim().toLowerCase()] ??
32
+ WA_COMPANION_PLATFORM_IDS.OTHER_WEB_CLIENT);
41
33
  }
@@ -1,12 +1,14 @@
1
1
  export { getWaCompanionPlatformId, WA_BROWSERS, WA_COMPANION_PLATFORM_IDS } from './browser.js';
2
2
  export { WA_SIGNALING, WA_PAIRING_KDF_INFO } from './auth.js';
3
- export { WA_DISCONNECT_REASONS, WA_LOGOUT_REASONS, WA_READY_STATES, WA_STREAM_SIGNALING } from './stream.js';
3
+ export { WA_CONNECTION_REASONS, WA_DISCONNECT_REASONS, WA_FAILURE_REASONS, WA_LOGOUT_REASONS, WA_READY_STATES, WA_STREAM_SIGNALING } from './stream.js';
4
4
  export { WA_IQ_TYPES, WA_NODE_TAGS, WA_XMLNS } from './nodes.js';
5
- export { WA_MESSAGE_TAGS, WA_MESSAGE_TYPES, WA_RETRYABLE_ACK_CODES } from './message.js';
6
- export { WA_APP_STATE_COLLECTIONS, WA_APP_STATE_COLLECTION_STATES, WA_APP_STATE_CHAT_MUTATION_ACTIONS, WA_APP_STATE_CHAT_MUTATION_SPECS, WA_APP_STATE_ERROR_CODES, WA_APP_STATE_KDF_INFO, WA_APP_STATE_KEY_TYPES, WA_APP_STATE_SYNC_DATA_TYPE } from './appstate.js';
5
+ export { WA_EDIT_ATTRS, WA_ENC_MEDIA_TYPES, WA_EVENT_META_TYPES, WA_MESSAGE_TAGS, WA_MESSAGE_TYPES, WA_POLL_META_TYPES, WA_RETRYABLE_ACK_CODES, WA_STANZA_MSG_TYPES } from './message.js';
6
+ export { WA_APP_STATE_COLLECTIONS, WA_APP_STATE_COLLECTION_STATES, WA_APP_STATE_CHAT_MUTATION_SPECS, WA_APP_STATE_ERROR_CODES, WA_APP_STATE_KDF_INFO, WA_APP_STATE_KEY_TYPES, WA_APP_STATE_SYNC_DATA_TYPE } from './appstate.js';
7
7
  export { getWaMediaHkdfInfo, WA_MEDIA_HKDF_INFO, WA_PREVIEW_MEDIA_HKDF_INFO } from './media.js';
8
8
  export { WA_ACCOUNT_SYNC_PROTOCOLS, WA_DIRTY_PROTOCOLS, WA_DIRTY_TYPES, WA_SUPPORTED_DIRTY_TYPES } from './dirty.js';
9
9
  export { WA_GROUP_NOTIFICATION_TAGS, WA_NOTIFICATION_TYPES } from './notification.js';
10
+ export { WA_PRIVACY_TOKEN_NOTIFICATION_TYPE, WA_PRIVACY_TOKEN_TAGS, WA_PRIVACY_TOKEN_TYPES, WA_TC_TOKEN_DEFAULTS } from './privacy-token.js';
11
+ export { WA_PRIVACY_CATEGORIES, WA_PRIVACY_CATEGORY_TO_SETTING, WA_PRIVACY_DISALLOWED_LIST_CATEGORIES, WA_PRIVACY_SETTING_TO_CATEGORY, WA_PRIVACY_TAGS, WA_PRIVACY_VALUES } from './privacy.js';
10
12
  export { WA_DEFAULTS } from './defaults.js';
11
13
  export { WA_GROUP_PARTICIPANT_TYPES } from './group.js';
12
14
  export { WA_USYNC_CONTEXTS, WA_USYNC_DEFAULTS, WA_USYNC_MODES } from './usync.js';
@@ -3,6 +3,12 @@ export const WA_DEFAULTS = Object.freeze({
3
3
  HOST_DOMAIN: 's.whatsapp.net',
4
4
  GROUP_SERVER: 'g.us',
5
5
  BROADCAST_SERVER: 'broadcast',
6
+ LID_SERVER: 'lid',
7
+ HOSTED_SERVER: 'hosted',
8
+ HOSTED_LID_SERVER: 'hosted.lid',
9
+ HOSTED_DEVICE_ID: 99,
10
+ MSGR_SERVER: 'msgr',
11
+ INTEROP_SERVER: 'interop',
6
12
  DEVICE_BROWSER: WA_BROWSERS.FIREFOX,
7
13
  DEVICE_PLATFORM: getWaCompanionPlatformId(WA_BROWSERS.FIREFOX),
8
14
  CHAT_SOCKET_URLS: ['wss://web.whatsapp.com/ws/chat', 'wss://web.whatsapp.com:5222/ws/chat'],
@@ -1,3 +1,2 @@
1
1
  export * from './constants.js';
2
- export { getLoginIdentity, isGroupJid, normalizeDeviceJid, normalizeRecipientJid, parsePhoneJid, parseSignalAddressFromJid, splitJid, toUserJid } from './jid.js';
3
- export { WA_USYNC_CONTEXTS, WA_USYNC_DEFAULTS, WA_USYNC_MODES } from './usync.js';
2
+ export { buildDeviceJid, canonicalizeSignalJid, canonicalizeSignalServer, getLoginIdentity, isHostedDeviceId, isHostedDeviceJid, isHostedServer, isGroupJid, normalizeDeviceJid, normalizeRecipientJid, parsePhoneJid, parseSignalAddressFromJid, splitJid, signalAddressKey, toUserJid } from './jid.js';
@@ -1,51 +1,62 @@
1
1
  import { WA_DEFAULTS } from './constants.js';
2
- function scanJid(jid) {
3
- let atIndex = -1;
4
- let colonIndex = -1;
5
- let dotIndex = -1;
6
- for (let index = 0; index < jid.length; index++) {
7
- const code = jid.charCodeAt(index);
8
- if (code === 64) {
9
- atIndex = index;
10
- break;
11
- }
12
- if (code === 58 && colonIndex === -1)
13
- colonIndex = index;
14
- else if (code === 46 && dotIndex === -1 && colonIndex === -1)
15
- dotIndex = index;
2
+ const KNOWN_SERVERS = {
3
+ [WA_DEFAULTS.HOST_DOMAIN]: WA_DEFAULTS.HOST_DOMAIN,
4
+ [WA_DEFAULTS.GROUP_SERVER]: WA_DEFAULTS.GROUP_SERVER,
5
+ [WA_DEFAULTS.BROADCAST_SERVER]: WA_DEFAULTS.BROADCAST_SERVER,
6
+ [WA_DEFAULTS.LID_SERVER]: WA_DEFAULTS.LID_SERVER,
7
+ [WA_DEFAULTS.HOSTED_SERVER]: WA_DEFAULTS.HOSTED_SERVER,
8
+ [WA_DEFAULTS.HOSTED_LID_SERVER]: WA_DEFAULTS.HOSTED_LID_SERVER,
9
+ [WA_DEFAULTS.MSGR_SERVER]: WA_DEFAULTS.MSGR_SERVER,
10
+ [WA_DEFAULTS.INTEROP_SERVER]: WA_DEFAULTS.INTEROP_SERVER
11
+ };
12
+ /**
13
+ * Returns the canonical reference for known server strings, avoiding
14
+ * thousands of duplicate sliced copies (e.g. "lid", "s.whatsapp.net")
15
+ * that would otherwise be created by repeated JID parsing.
16
+ */
17
+ function internServer(server) {
18
+ return KNOWN_SERVERS[server] ?? server;
19
+ }
20
+ function extractDigits(input) {
21
+ let digits = '';
22
+ for (let index = 0; index < input.length; index += 1) {
23
+ const code = input.charCodeAt(index);
24
+ if (code >= 48 && code <= 57)
25
+ digits += input[index];
16
26
  }
27
+ return digits;
28
+ }
29
+ function findAtIndex(jid) {
30
+ const atIndex = jid.indexOf('@');
17
31
  if (atIndex < 1 || atIndex >= jid.length - 1)
18
32
  throw new Error(`invalid jid: ${jid}`);
19
- return { atIndex, colonIndex, dotIndex };
33
+ return atIndex;
20
34
  }
21
35
  export function splitJid(jid) {
22
- const { atIndex } = scanJid(jid);
23
- return { user: jid.slice(0, atIndex), server: jid.slice(atIndex + 1) };
36
+ const atIndex = findAtIndex(jid);
37
+ return { user: jid.slice(0, atIndex), server: internServer(jid.slice(atIndex + 1)) };
24
38
  }
25
39
  export function normalizeRecipientJid(to) {
26
40
  const input = to.trim();
27
41
  if (input.length === 0)
28
42
  throw new Error('recipient cannot be empty');
29
43
  let hasDash = false;
30
- let digits = '';
31
44
  for (let index = 0; index < input.length; index += 1) {
32
45
  const code = input.charCodeAt(index);
33
46
  if (code === 64)
34
47
  return input;
35
48
  if (code === 45) {
36
49
  hasDash = true;
37
- continue;
38
50
  }
39
- if (code >= 48 && code <= 57)
40
- digits += input[index];
41
51
  }
52
+ const digits = extractDigits(input);
42
53
  if (hasDash)
43
54
  return `${input}@${WA_DEFAULTS.GROUP_SERVER}`;
44
55
  if (digits.length === 0)
45
56
  throw new Error(`invalid recipient: ${to}`);
46
57
  return `${digits}@${WA_DEFAULTS.HOST_DOMAIN}`;
47
58
  }
48
- export function isJidType(jid, type) {
59
+ function isJidType(jid, type) {
49
60
  const atIndex = jid.length - type.length - 1;
50
61
  return atIndex >= 1 && jid.charCodeAt(atIndex) === 64 && jid.endsWith(type);
51
62
  }
@@ -59,18 +70,43 @@ export function isGroupOrBroadcastJid(jid) {
59
70
  return isGroupJid(jid) || isBroadcastJid(jid);
60
71
  }
61
72
  export function parseSignalAddressFromJid(jid) {
62
- const { atIndex, colonIndex } = scanJid(jid);
63
- const server = jid.slice(atIndex + 1);
64
- if (colonIndex === -1)
73
+ const atIndex = findAtIndex(jid);
74
+ const colonIndex = jid.indexOf(':', 0);
75
+ const server = internServer(jid.slice(atIndex + 1));
76
+ if (colonIndex === -1 || colonIndex > atIndex) {
65
77
  return { user: jid.slice(0, atIndex), server, device: 0 };
78
+ }
66
79
  const device = Number.parseInt(jid.slice(colonIndex + 1, atIndex), 10);
67
80
  if (!Number.isFinite(device) || device < 0)
68
81
  throw new Error(`invalid jid device: ${jid}`);
69
82
  return { user: jid.slice(0, colonIndex), server, device };
70
83
  }
71
- export function toUserJid(jid) {
84
+ export function parseJidFull(jid) {
85
+ const address = parseSignalAddressFromJid(jid);
86
+ const userJid = `${address.user}@${address.server}`;
87
+ const normalizedJid = address.device === 0 ? userJid : `${address.user}:${address.device}@${address.server}`;
88
+ return { address, userJid, normalizedJid };
89
+ }
90
+ export function canonicalizeSignalServer(server, hostDomain = WA_DEFAULTS.HOST_DOMAIN) {
91
+ if (server === WA_DEFAULTS.HOSTED_SERVER)
92
+ return hostDomain;
93
+ if (server === WA_DEFAULTS.HOSTED_LID_SERVER)
94
+ return WA_DEFAULTS.LID_SERVER;
95
+ return server;
96
+ }
97
+ export function canonicalizeSignalJid(jid, hostDomain = WA_DEFAULTS.HOST_DOMAIN) {
72
98
  const address = parseSignalAddressFromJid(jid);
73
- return `${address.user}@${address.server}`;
99
+ const server = canonicalizeSignalServer(address.server ?? WA_DEFAULTS.HOST_DOMAIN, hostDomain);
100
+ if (address.device === 0)
101
+ return `${address.user}@${server}`;
102
+ return `${address.user}:${address.device}@${server}`;
103
+ }
104
+ export function toUserJid(jid, options = {}) {
105
+ const address = parseSignalAddressFromJid(jid);
106
+ const server = options.canonicalizeSignalServer === true
107
+ ? canonicalizeSignalServer(address.server ?? WA_DEFAULTS.HOST_DOMAIN, options.hostDomain ?? WA_DEFAULTS.HOST_DOMAIN)
108
+ : address.server;
109
+ return `${address.user}@${server}`;
74
110
  }
75
111
  export function normalizeDeviceJid(jid) {
76
112
  const address = parseSignalAddressFromJid(jid);
@@ -78,11 +114,49 @@ export function normalizeDeviceJid(jid) {
78
114
  return `${address.user}@${address.server}`;
79
115
  return `${address.user}:${address.device}@${address.server}`;
80
116
  }
117
+ export function isHostedDeviceId(deviceId) {
118
+ return deviceId === WA_DEFAULTS.HOSTED_DEVICE_ID;
119
+ }
120
+ export function isHostedServer(server) {
121
+ return server === WA_DEFAULTS.HOSTED_SERVER || server === WA_DEFAULTS.HOSTED_LID_SERVER;
122
+ }
123
+ export function isHostedDeviceJid(jid) {
124
+ const { user, server } = splitJid(jid);
125
+ if (isHostedServer(server)) {
126
+ return true;
127
+ }
128
+ const colonIndex = user.indexOf(':');
129
+ if (colonIndex < 0) {
130
+ return false;
131
+ }
132
+ const deviceId = Number.parseInt(user.slice(colonIndex + 1), 10);
133
+ return Number.isSafeInteger(deviceId) && isHostedDeviceId(deviceId);
134
+ }
135
+ export function buildDeviceJid(user, normalizedServer, deviceId, options = {}) {
136
+ if (options.isHosted === true) {
137
+ if (!isHostedDeviceId(deviceId)) {
138
+ return `${user}:${deviceId}@${normalizedServer}`;
139
+ }
140
+ const hostedServer = options.rawServer === WA_DEFAULTS.HOSTED_LID_SERVER ||
141
+ normalizedServer === WA_DEFAULTS.LID_SERVER
142
+ ? WA_DEFAULTS.HOSTED_LID_SERVER
143
+ : WA_DEFAULTS.HOSTED_SERVER;
144
+ return `${user}:${WA_DEFAULTS.HOSTED_DEVICE_ID}@${hostedServer}`;
145
+ }
146
+ if (deviceId === 0) {
147
+ return `${user}@${normalizedServer}`;
148
+ }
149
+ return `${user}:${deviceId}@${normalizedServer}`;
150
+ }
81
151
  export function getLoginIdentity(meJid) {
82
- const { atIndex, colonIndex, dotIndex } = scanJid(meJid);
83
- const userEndIndex = dotIndex === -1 ? (colonIndex === -1 ? atIndex : colonIndex) : dotIndex;
152
+ const atIndex = findAtIndex(meJid);
153
+ const colonIndex = meJid.indexOf(':', 0);
154
+ const dotIndex = meJid.indexOf('.', 0);
155
+ const hasColon = colonIndex !== -1 && colonIndex < atIndex;
156
+ const hasDot = dotIndex !== -1 && dotIndex < atIndex && (colonIndex === -1 || dotIndex < colonIndex);
157
+ const userEndIndex = hasDot ? dotIndex : hasColon ? colonIndex : atIndex;
84
158
  const username = Number.parseInt(meJid.slice(0, userEndIndex), 10);
85
- const device = colonIndex === -1 ? 0 : Number.parseInt(meJid.slice(colonIndex + 1, atIndex), 10);
159
+ const device = hasColon ? Number.parseInt(meJid.slice(colonIndex + 1, atIndex), 10) : 0;
86
160
  if (!Number.isSafeInteger(username) || username <= 0)
87
161
  throw new Error(`invalid numeric username from ${meJid}`);
88
162
  if (!Number.isSafeInteger(device) || device < 0)
@@ -90,12 +164,7 @@ export function getLoginIdentity(meJid) {
90
164
  return { username, device };
91
165
  }
92
166
  export function parsePhoneJid(input) {
93
- let digits = '';
94
- for (let index = 0; index < input.length; index += 1) {
95
- const code = input.charCodeAt(index);
96
- if (code >= 48 && code <= 57)
97
- digits += input[index];
98
- }
167
+ const digits = extractDigits(input);
99
168
  if (!digits)
100
169
  throw new Error('phone number is empty after normalization');
101
170
  return `${digits}@${WA_DEFAULTS.HOST_DOMAIN}`;