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
@@ -0,0 +1,65 @@
1
+ import { WA_DEFAULTS } from '../../../protocol/defaults.js';
2
+ import { WA_EMAIL_LIMITS, WA_EMAIL_TAGS, WA_EMAIL_XMLNS } from '../../../protocol/email.js';
3
+ import { buildIqNode } from '../../node/query.js';
4
+ export function buildGetEmailIq() {
5
+ return buildIqNode('get', WA_DEFAULTS.HOST_DOMAIN, WA_EMAIL_XMLNS, [
6
+ { tag: WA_EMAIL_TAGS.EMAIL, attrs: {} }
7
+ ]);
8
+ }
9
+ export function buildSetEmailIq(email, context) {
10
+ if (email.length === 0 || email.length > WA_EMAIL_LIMITS.EMAIL_MAX_LENGTH) {
11
+ throw new Error(`email length must be between 1 and ${WA_EMAIL_LIMITS.EMAIL_MAX_LENGTH} chars`);
12
+ }
13
+ const emailChildren = [];
14
+ if (context !== undefined) {
15
+ emailChildren.push({ tag: WA_EMAIL_TAGS.CONTEXT, attrs: {}, content: context });
16
+ }
17
+ emailChildren.push({ tag: WA_EMAIL_TAGS.EMAIL_ADDRESS, attrs: {}, content: email });
18
+ return buildIqNode('set', WA_DEFAULTS.HOST_DOMAIN, WA_EMAIL_XMLNS, [
19
+ { tag: WA_EMAIL_TAGS.EMAIL, attrs: {}, content: emailChildren }
20
+ ]);
21
+ }
22
+ export function buildRequestEmailVerificationCodeIq(input) {
23
+ assertLocaleField('languageCode', input.languageCode);
24
+ assertLocaleField('localeCode', input.localeCode);
25
+ return buildIqNode('set', WA_DEFAULTS.HOST_DOMAIN, WA_EMAIL_XMLNS, [
26
+ {
27
+ tag: WA_EMAIL_TAGS.VERIFY_EMAIL,
28
+ attrs: {},
29
+ content: [
30
+ { tag: WA_EMAIL_TAGS.LG, attrs: {}, content: input.languageCode },
31
+ { tag: WA_EMAIL_TAGS.LC, attrs: {}, content: input.localeCode }
32
+ ]
33
+ }
34
+ ]);
35
+ }
36
+ export function buildVerifyEmailCodeIq(code) {
37
+ if (code.length !== WA_EMAIL_LIMITS.CODE_LENGTH) {
38
+ throw new Error(`verification code must be exactly ${WA_EMAIL_LIMITS.CODE_LENGTH} chars`);
39
+ }
40
+ return buildIqNode('set', WA_DEFAULTS.HOST_DOMAIN, WA_EMAIL_XMLNS, [
41
+ {
42
+ tag: WA_EMAIL_TAGS.VERIFY_EMAIL,
43
+ attrs: {},
44
+ content: [{ tag: WA_EMAIL_TAGS.CODE, attrs: {}, content: code }]
45
+ }
46
+ ]);
47
+ }
48
+ export function buildConfirmEmailIq(context) {
49
+ const children = context !== undefined
50
+ ? [{ tag: WA_EMAIL_TAGS.CONTEXT, attrs: {}, content: context }]
51
+ : undefined;
52
+ return buildIqNode('set', WA_DEFAULTS.HOST_DOMAIN, WA_EMAIL_XMLNS, [
53
+ {
54
+ tag: WA_EMAIL_TAGS.CONFIRM_EMAIL,
55
+ attrs: {},
56
+ ...(children !== undefined ? { content: children } : {})
57
+ }
58
+ ]);
59
+ }
60
+ function assertLocaleField(field, value) {
61
+ if (value.length < WA_EMAIL_LIMITS.LOCALE_MIN_LENGTH ||
62
+ value.length > WA_EMAIL_LIMITS.LOCALE_MAX_LENGTH) {
63
+ throw new Error(`${field} must be between ${WA_EMAIL_LIMITS.LOCALE_MIN_LENGTH} and ${WA_EMAIL_LIMITS.LOCALE_MAX_LENGTH} chars`);
64
+ }
65
+ }
@@ -0,0 +1,14 @@
1
+ import { WA_NODE_TAGS } from '../../../protocol/constants.js';
2
+ export function buildOfflineBatchNode(count) {
3
+ return {
4
+ tag: WA_NODE_TAGS.INFO_BULLETIN,
5
+ attrs: {},
6
+ content: [
7
+ {
8
+ tag: 'offline_batch',
9
+ attrs: { count: String(count) },
10
+ content: undefined
11
+ }
12
+ ]
13
+ };
14
+ }
@@ -1,7 +1,8 @@
1
+ import { toRawPubKey } from '../../../crypto/core/keys.js';
1
2
  import { WA_DEFAULTS, WA_NODE_TAGS, WA_XMLNS } from '../../../protocol/constants.js';
2
3
  import { SIGNAL_KEY_BUNDLE_TYPE_BYTES } from '../../../signal/api/constants.js';
3
4
  import { buildIqNode } from '../../node/query.js';
4
- import { intToBytes, toBytesView } from '../../../util/bytes.js';
5
+ import { intToBytes } from '../../../util/bytes.js';
5
6
  function buildSignedPreKeyNode(signedPreKey) {
6
7
  return {
7
8
  tag: WA_NODE_TAGS.SKEY,
@@ -15,55 +16,51 @@ function buildSignedPreKeyNode(signedPreKey) {
15
16
  {
16
17
  tag: WA_NODE_TAGS.VALUE,
17
18
  attrs: {},
18
- content: toBytesView(signedPreKey.keyPair.pubKey)
19
+ content: toRawPubKey(signedPreKey.keyPair.pubKey)
19
20
  },
20
21
  {
21
22
  tag: WA_NODE_TAGS.SIGNATURE,
22
23
  attrs: {},
23
- content: toBytesView(signedPreKey.signature)
24
+ content: signedPreKey.signature
24
25
  }
25
26
  ]
26
27
  };
27
28
  }
28
29
  export function buildPreKeyUploadIq(registrationInfo, signedPreKey, preKeys) {
29
- return buildIqNode('set', WA_DEFAULTS.HOST_DOMAIN, WA_XMLNS.SIGNAL, [
30
- {
31
- tag: WA_NODE_TAGS.REGISTRATION,
32
- attrs: {},
33
- content: intToBytes(4, registrationInfo.registrationId)
34
- },
35
- {
36
- tag: WA_NODE_TAGS.TYPE,
37
- attrs: {},
38
- content: SIGNAL_KEY_BUNDLE_TYPE_BYTES
39
- },
40
- {
41
- tag: WA_NODE_TAGS.IDENTITY,
42
- attrs: {},
43
- content: toBytesView(registrationInfo.identityKeyPair.pubKey)
44
- },
45
- {
46
- tag: WA_NODE_TAGS.LIST,
30
+ const children = [];
31
+ children.push({
32
+ tag: WA_NODE_TAGS.IDENTITY,
33
+ attrs: {},
34
+ content: toRawPubKey(registrationInfo.identityKeyPair.pubKey)
35
+ }, {
36
+ tag: WA_NODE_TAGS.REGISTRATION,
37
+ attrs: {},
38
+ content: intToBytes(4, registrationInfo.registrationId)
39
+ }, {
40
+ tag: WA_NODE_TAGS.TYPE,
41
+ attrs: {},
42
+ content: SIGNAL_KEY_BUNDLE_TYPE_BYTES
43
+ }, {
44
+ tag: WA_NODE_TAGS.LIST,
45
+ attrs: {},
46
+ content: preKeys.map((record) => ({
47
+ tag: WA_NODE_TAGS.KEY,
47
48
  attrs: {},
48
- content: preKeys.map((record) => ({
49
- tag: WA_NODE_TAGS.KEY,
50
- attrs: {},
51
- content: [
52
- {
53
- tag: WA_NODE_TAGS.ID,
54
- attrs: {},
55
- content: intToBytes(3, record.keyId)
56
- },
57
- {
58
- tag: WA_NODE_TAGS.VALUE,
59
- attrs: {},
60
- content: toBytesView(record.keyPair.pubKey)
61
- }
62
- ]
63
- }))
64
- },
65
- buildSignedPreKeyNode(signedPreKey)
66
- ]);
49
+ content: [
50
+ {
51
+ tag: WA_NODE_TAGS.ID,
52
+ attrs: {},
53
+ content: intToBytes(3, record.keyId)
54
+ },
55
+ {
56
+ tag: WA_NODE_TAGS.VALUE,
57
+ attrs: {},
58
+ content: toRawPubKey(record.keyPair.pubKey)
59
+ }
60
+ ]
61
+ }))
62
+ }, buildSignedPreKeyNode(signedPreKey));
63
+ return buildIqNode('set', WA_DEFAULTS.HOST_DOMAIN, WA_XMLNS.SIGNAL, children);
67
64
  }
68
65
  export function buildSignedPreKeyRotateIq(signedPreKey) {
69
66
  return buildIqNode('set', WA_DEFAULTS.HOST_DOMAIN, WA_XMLNS.SIGNAL, [
@@ -0,0 +1,13 @@
1
+ export function buildPresenceNode(input) {
2
+ const attrs = {};
3
+ if (input?.type) {
4
+ attrs.type = input.type;
5
+ }
6
+ if (input?.name) {
7
+ attrs.name = input.name;
8
+ }
9
+ return {
10
+ tag: 'presence',
11
+ attrs
12
+ };
13
+ }
@@ -1,29 +1,25 @@
1
- import { WA_IQ_TYPES, WA_NODE_TAGS, WA_XMLNS } from '../../../protocol/nodes.js';
1
+ import { WA_DEFAULTS } from '../../../protocol/defaults.js';
2
+ import { toUserJid } from '../../../protocol/jid.js';
3
+ import { WA_XMLNS } from '../../../protocol/nodes.js';
2
4
  import { WA_PRIVACY_TOKEN_TAGS, WA_PRIVACY_TOKEN_TYPES } from '../../../protocol/privacy-token.js';
5
+ import { buildIqNode } from '../../node/query.js';
3
6
  export function buildPrivacyTokenIqNode(input) {
4
- return {
5
- tag: WA_NODE_TAGS.IQ,
6
- attrs: {
7
- type: WA_IQ_TYPES.SET,
8
- xmlns: WA_XMLNS.PRIVACY
9
- },
10
- content: [
11
- {
12
- tag: WA_PRIVACY_TOKEN_TAGS.TOKENS,
13
- attrs: {},
14
- content: [
15
- {
16
- tag: WA_PRIVACY_TOKEN_TAGS.TOKEN,
17
- attrs: {
18
- jid: input.jid,
19
- t: String(input.timestampS),
20
- type: input.type ?? WA_PRIVACY_TOKEN_TYPES.TRUSTED_CONTACT
21
- }
7
+ return buildIqNode('set', WA_DEFAULTS.HOST_DOMAIN, WA_XMLNS.PRIVACY, [
8
+ {
9
+ tag: WA_PRIVACY_TOKEN_TAGS.TOKENS,
10
+ attrs: {},
11
+ content: [
12
+ {
13
+ tag: WA_PRIVACY_TOKEN_TAGS.TOKEN,
14
+ attrs: {
15
+ jid: toUserJid(input.jid),
16
+ t: String(input.timestampS),
17
+ type: input.type ?? WA_PRIVACY_TOKEN_TYPES.TRUSTED_CONTACT
22
18
  }
23
- ]
24
- }
25
- ]
26
- };
19
+ }
20
+ ]
21
+ }
22
+ ]);
27
23
  }
28
24
  export function buildTcTokenMessageNode(token) {
29
25
  return {
@@ -75,7 +75,7 @@ export function buildRetryReceiptNode(input) {
75
75
  id: input.originalMsgId,
76
76
  t: input.t
77
77
  };
78
- if (input.error !== undefined) {
78
+ if (input.error !== undefined && input.error !== 0) {
79
79
  retryAttrs.error = String(input.error);
80
80
  }
81
81
  const content = [
@@ -126,6 +126,14 @@ export function decodeNodeContentUtf8OrBytes(value, field) {
126
126
  }
127
127
  throw new Error(`node ${field} has no binary content`);
128
128
  }
129
+ export function getNodeTextContent(node) {
130
+ const content = node.content;
131
+ if (content instanceof Uint8Array)
132
+ return TEXT_DECODER.decode(content);
133
+ if (typeof content === 'string')
134
+ return content;
135
+ return undefined;
136
+ }
129
137
  export function decodeNodeContentBase64OrBytes(value, field) {
130
138
  if (value === null || value === undefined) {
131
139
  throw new Error(`missing binary node content for ${field}`);
@@ -155,3 +163,19 @@ export async function createNodeIdGenerator() {
155
163
  }
156
164
  };
157
165
  }
166
+ export function createMobileNodeIdGenerator() {
167
+ let featureCounter = 0;
168
+ let systemCounter = 0;
169
+ return {
170
+ prefix: '0',
171
+ next() {
172
+ const id = `0${featureCounter.toString(16)}`;
173
+ featureCounter = (featureCounter + 1) & 0xffff;
174
+ return id;
175
+ },
176
+ nextSystem() {
177
+ systemCounter = (systemCounter + 1) & 0xffff;
178
+ return systemCounter.toString(16);
179
+ }
180
+ };
181
+ }
@@ -0,0 +1,152 @@
1
+ import { TEXT_DECODER } from '../../../util/bytes.js';
2
+ let cachedArgo;
3
+ async function loadArgo() {
4
+ if (cachedArgo !== undefined)
5
+ return cachedArgo;
6
+ try {
7
+ cachedArgo = (await import('argo-codec'));
8
+ }
9
+ catch {
10
+ cachedArgo = null;
11
+ }
12
+ return cachedArgo;
13
+ }
14
+ export async function isMexArgoDecoderAvailable() {
15
+ return (await loadArgo()) !== null;
16
+ }
17
+ const LABEL_NULL = -1;
18
+ const LABEL_ABSENT = -2;
19
+ const BACKREF_BASE = -4;
20
+ const DESC_NULL = -1;
21
+ const DESC_FALSE = 0;
22
+ const DESC_TRUE = 1;
23
+ const DESC_OBJECT = 2;
24
+ const DESC_LIST = 3;
25
+ const DESC_STRING = 4;
26
+ const DESC_BYTES = 5;
27
+ const DESC_INT = 6;
28
+ const DESC_FLOAT = 7;
29
+ const FLAG_INLINE_EVERYTHING = 1 << 0;
30
+ const FLAG_HAS_USER_FLAGS = 1 << 6;
31
+ export async function decodeMexArgoResponse(bytes) {
32
+ const argo = await loadArgo();
33
+ if (!argo)
34
+ throw new Error('argo-codec not installed');
35
+ const r = new argo.Reader(bytes);
36
+ const flags = r.bitset();
37
+ const inline = (flags & FLAG_INLINE_EVERYTHING) !== 0;
38
+ if (flags & FLAG_HAS_USER_FLAGS)
39
+ r.bitset();
40
+ const segments = [];
41
+ if (!inline) {
42
+ while (r.pos < r.end) {
43
+ const len = r.label();
44
+ segments.push(new argo.Reader(r.bytes(len)));
45
+ }
46
+ if (segments.length === 0)
47
+ throw new Error('mex argo: missing core segment');
48
+ }
49
+ else {
50
+ segments.push(r);
51
+ }
52
+ const core = segments[segments.length - 1];
53
+ const blocks = inline ? new Map() : indexBlocks(segments.slice(0, -1));
54
+ const ctx = { core, blocks, stringSeen: [] };
55
+ const data = readDesc(ctx);
56
+ const errors = [];
57
+ if (core.pos < core.end) {
58
+ const errCount = core.label();
59
+ for (let i = 0; i < errCount; i++)
60
+ errors.push(readError(ctx));
61
+ }
62
+ return { data, errors };
63
+ }
64
+ function indexBlocks(slices) {
65
+ const m = new Map();
66
+ const keys = ['String', 'Int', 'Float', 'Bytes'];
67
+ for (let i = 0; i < slices.length && i < keys.length; i++)
68
+ m.set(keys[i], slices[i]);
69
+ return m;
70
+ }
71
+ function getBlock(ctx, key) {
72
+ const b = ctx.blocks.get(key);
73
+ if (!b)
74
+ throw new Error(`mex argo: block '${key}' missing`);
75
+ return b;
76
+ }
77
+ function readStringFromBlock(ctx) {
78
+ const lab = ctx.core.label();
79
+ if (lab < BACKREF_BASE + 1) {
80
+ const idx = -lab + BACKREF_BASE;
81
+ return ctx.stringSeen[idx];
82
+ }
83
+ const block = getBlock(ctx, 'String');
84
+ const s = TEXT_DECODER.decode(block.bytes(lab));
85
+ ctx.stringSeen.push(s);
86
+ return s;
87
+ }
88
+ function readDesc(ctx) {
89
+ const m = ctx.core.label();
90
+ switch (m) {
91
+ case DESC_NULL:
92
+ return null;
93
+ case DESC_FALSE:
94
+ return false;
95
+ case DESC_TRUE:
96
+ return true;
97
+ case DESC_STRING:
98
+ return readStringFromBlock(ctx);
99
+ case DESC_INT:
100
+ return getBlock(ctx, 'Int').label();
101
+ case DESC_FLOAT:
102
+ throw new Error('mex argo: DESC_FLOAT not implemented');
103
+ case DESC_BYTES:
104
+ throw new Error('mex argo: DESC_BYTES not implemented');
105
+ case DESC_LIST: {
106
+ const n = ctx.core.label();
107
+ const out = [];
108
+ for (let i = 0; i < n; i++)
109
+ out.push(readDesc(ctx));
110
+ return out;
111
+ }
112
+ case DESC_OBJECT: {
113
+ const n = ctx.core.label();
114
+ const out = {};
115
+ for (let i = 0; i < n; i++) {
116
+ const key = readStringFromBlock(ctx);
117
+ out[key] = readDesc(ctx);
118
+ }
119
+ return out;
120
+ }
121
+ default:
122
+ throw new Error(`mex argo: unknown DESC marker ${m}`);
123
+ }
124
+ }
125
+ function readError(ctx) {
126
+ const message = readStringFromBlock(ctx);
127
+ skipOptional(ctx); // location — never observed in MEX errors so far
128
+ const path = readPath(ctx);
129
+ const extensions = readOptionalDesc(ctx);
130
+ return { message, path, extensions };
131
+ }
132
+ function skipOptional(ctx) {
133
+ const lab = ctx.core.label();
134
+ if (lab !== LABEL_ABSENT && lab !== LABEL_NULL) {
135
+ // Present but not yet structurally decoded; would need a typed inner read here.
136
+ // For locations specifically we have no observed sample; bail loudly if hit.
137
+ throw new Error(`mex argo: unexpected optional present (lab=${lab}); add support`);
138
+ }
139
+ }
140
+ function readPath(ctx) {
141
+ const lab = ctx.core.label();
142
+ if (lab === LABEL_ABSENT || lab === LABEL_NULL)
143
+ return null;
144
+ return lab;
145
+ }
146
+ function readOptionalDesc(ctx) {
147
+ const lab = ctx.core.label();
148
+ if (lab === LABEL_ABSENT || lab === LABEL_NULL)
149
+ return null;
150
+ const v = readDesc(ctx);
151
+ return typeof v === 'object' && v !== null ? v : null;
152
+ }
@@ -0,0 +1,83 @@
1
+ import { WA_DEFAULTS, WA_IQ_TYPES, WA_NODE_TAGS, WA_XMLNS } from '../../../protocol/constants.js';
2
+ import { decodeNodeContentUtf8OrBytes, findNodeChild } from '../../node/helpers.js';
3
+ import { decodeMexArgoResponse, isMexArgoDecoderAvailable } from '../../node/mex/argo-decoder.js';
4
+ import { assertIqResult } from '../../node/query.js';
5
+ import { TEXT_DECODER } from '../../../util/bytes.js';
6
+ import { toError } from '../../../util/primitives.js';
7
+ const MEX_DEFAULT_TIMEOUT_MS = 32000;
8
+ export async function dispatchMexQuery(socket, args) {
9
+ const body = JSON.stringify({
10
+ queryId: args.clientDocId,
11
+ variables: args.variables
12
+ });
13
+ const node = {
14
+ tag: WA_NODE_TAGS.IQ,
15
+ attrs: {
16
+ ...(args.iqId ? { id: args.iqId } : {}),
17
+ to: WA_DEFAULTS.HOST_DOMAIN,
18
+ type: WA_IQ_TYPES.GET,
19
+ xmlns: WA_XMLNS.MEX
20
+ },
21
+ content: [
22
+ {
23
+ tag: 'query',
24
+ attrs: { query_id: args.docId },
25
+ content: body
26
+ }
27
+ ]
28
+ };
29
+ const response = await socket.query(node, args.timeoutMs ?? MEX_DEFAULT_TIMEOUT_MS);
30
+ assertIqResult(response, `mex/${args.opName}`);
31
+ const data = await parseMexResultPayload(response, args.opName);
32
+ return { raw: response, data };
33
+ }
34
+ async function parseMexResultPayload(node, opName) {
35
+ const result = findNodeChild(node, 'result');
36
+ if (!result) {
37
+ throw new Error(`mex/${opName} response missing <result>`);
38
+ }
39
+ const format = result.attrs.format ?? 'json';
40
+ const rawBytes = decodeNodeContentUtf8OrBytes(result.content, `mex/${opName}/result`);
41
+ if (format === 'argo') {
42
+ if (!(await isMexArgoDecoderAvailable())) {
43
+ throw new Error(`mex/${opName} argo response received but 'argo-codec' not installed; ${rawBytes.length}B; ` +
44
+ `strings: ${extractVisibleStrings(rawBytes)}`);
45
+ }
46
+ let decoded;
47
+ try {
48
+ decoded = await decodeMexArgoResponse(rawBytes);
49
+ }
50
+ catch (error) {
51
+ throw new Error(`mex/${opName} argo decode failed: ${toError(error).message}; ` +
52
+ `${rawBytes.length}B; strings: ${extractVisibleStrings(rawBytes)}`);
53
+ }
54
+ if (decoded.errors.length > 0) {
55
+ const summary = decoded.errors
56
+ .map((e) => {
57
+ const code = e.extensions?.error_code ?? e.extensions?.code ?? '?';
58
+ const sev = e.extensions?.severity;
59
+ return `${code}${sev ? `/${String(sev)}` : ''}: ${e.message} @${e.path ?? ''}`;
60
+ })
61
+ .join('; ');
62
+ throw new Error(`mex/${opName} errors: ${summary}`);
63
+ }
64
+ return decoded.data;
65
+ }
66
+ return extractGraphQlData(JSON.parse(TEXT_DECODER.decode(rawBytes)), opName);
67
+ }
68
+ function extractVisibleStrings(bytes) {
69
+ return TEXT_DECODER.decode(bytes)
70
+ .replace(/[\x00-\x1f\x7f-\xff]+/g, ' ')
71
+ .replace(/\s+/g, ' ')
72
+ .trim();
73
+ }
74
+ function extractGraphQlData(payload, opName) {
75
+ const json = (payload ?? {});
76
+ if (json.errors && json.errors.length > 0) {
77
+ const summary = json.errors
78
+ .map((e) => `${e.extensions?.error_code ?? '?'}: ${e.message ?? '?'} @${(e.path ?? []).join('.')}`)
79
+ .join('; ');
80
+ throw new Error(`mex/${opName} errors: ${summary}`);
81
+ }
82
+ return json.data ?? null;
83
+ }
@@ -0,0 +1,10 @@
1
+ export const WA_MEX_PERSIST_IDS = Object.freeze({
2
+ WWWGetCertificates: Object.freeze({
3
+ docId: '25094190163544446',
4
+ clientDocId: '16428758503015954638431529919'
5
+ }),
6
+ WWWCreateUser: Object.freeze({
7
+ docId: '8548056818544135',
8
+ clientDocId: '25777518041400352865446016972'
9
+ })
10
+ });
@@ -2,7 +2,7 @@ import { randomUUID } from 'node:crypto';
2
2
  import { md5Bytes } from '../../crypto/core/primitives.js';
3
3
  import { proto } from '../../proto.js';
4
4
  import { DEFAULT_VERSION_BASE } from '../noise/constants.js';
5
- import { intToBytes, toBytesView } from '../../util/bytes.js';
5
+ import { intToBytes } from '../../util/bytes.js';
6
6
  function parseVersion(versionBase) {
7
7
  const [p = '2', s = '3000', t = '0'] = versionBase.split('.');
8
8
  const primary = Number.parseInt(p, 10);
@@ -15,13 +15,20 @@ function parseVersion(versionBase) {
15
15
  }
16
16
  return { primary, secondary, tertiary };
17
17
  }
18
+ let cachedLocale = null;
18
19
  function resolveLocale() {
20
+ // The first `Intl.DateTimeFormat()` call triggers V8's lazy ICU init
21
+ // (tens of ms). The process locale does not change at runtime, so
22
+ // memoize after the first resolve.
23
+ if (cachedLocale !== null)
24
+ return cachedLocale;
19
25
  const locale = Intl.DateTimeFormat().resolvedOptions().locale || 'en-US';
20
26
  const [language = 'en', country = 'US'] = locale.split('-');
21
- return {
27
+ cachedLocale = Object.freeze({
22
28
  lg: language.toLowerCase(),
23
29
  lc: country.toUpperCase()
24
- };
30
+ });
31
+ return cachedLocale;
25
32
  }
26
33
  function defaultWebSubPlatform() {
27
34
  return proto.ClientPayload.WebInfo.WebSubPlatform.WEB_BROWSER;
@@ -144,16 +151,14 @@ export function buildRegistrationPayload(config) {
144
151
  const version = parseVersion(versionBase);
145
152
  const common = buildCommonPayload(config, version);
146
153
  const devicePairingData = {
147
- buildHash: config.buildHash ? toBytesView(config.buildHash) : md5Bytes(versionBase),
148
- deviceProps: config.deviceProps
149
- ? toBytesView(config.deviceProps)
150
- : defaultDeviceProps(versionBase, config, version),
154
+ buildHash: config.buildHash ?? md5Bytes(versionBase),
155
+ deviceProps: config.deviceProps ?? defaultDeviceProps(versionBase, config, version),
151
156
  eRegid: intToBytes(4, registrationId),
152
157
  eKeytype: intToBytes(1, 5),
153
- eIdent: toBytesView(config.registrationInfo.identityKeyPair.pubKey),
158
+ eIdent: config.registrationInfo.identityKeyPair.pubKey,
154
159
  eSkeyId: intToBytes(3, signedPreKeyId),
155
- eSkeyVal: toBytesView(config.signedPreKey.keyPair.pubKey),
156
- eSkeySig: toBytesView(config.signedPreKey.signature)
160
+ eSkeyVal: config.signedPreKey.keyPair.pubKey,
161
+ eSkeySig: config.signedPreKey.signature
157
162
  };
158
163
  return proto.ClientPayload.encode({
159
164
  ...common,
@@ -1,4 +1,4 @@
1
- import { EMPTY_BYTES, toBytesView } from '../../util/bytes.js';
1
+ import { EMPTY_BYTES } from '../../util/bytes.js';
2
2
  const WA_MAX_FRAME_LENGTH = (1 << 24) - 1;
3
3
  function frameLength(header) {
4
4
  return (header[0] << 16) | (header[1] << 8) | header[2];
@@ -11,7 +11,7 @@ export class WaFrameCodec {
11
11
  if (maxFrameLength >= 1 << 24) {
12
12
  throw new Error('maxFrameLength must be lower than protocol limit (16777216)');
13
13
  }
14
- this.introFrame = introFrame && introFrame.length > 0 ? toBytesView(introFrame) : null;
14
+ this.introFrame = introFrame && introFrame.length > 0 ? introFrame : null;
15
15
  this.maxFrameLength = maxFrameLength;
16
16
  this.introSent = false;
17
17
  this.buffered = EMPTY_BYTES;
@@ -0,0 +1,53 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { proto } from '../../proto.js';
3
+ function parseAppVersion(version) {
4
+ const parts = version.split('.');
5
+ const at = (i) => {
6
+ const n = Number(parts[i]);
7
+ return Number.isFinite(n) ? n : undefined;
8
+ };
9
+ return {
10
+ primary: at(0) ?? 2,
11
+ secondary: at(1) ?? 0,
12
+ tertiary: at(2) ?? 0,
13
+ quaternary: at(3)
14
+ };
15
+ }
16
+ export function buildMobileLoginPayload(config) {
17
+ if (!Number.isSafeInteger(config.username) || config.username <= 0) {
18
+ throw new Error('mobile login payload requires a valid numeric username');
19
+ }
20
+ const info = config.deviceInfo;
21
+ const version = parseAppVersion(info.appVersion);
22
+ const userAgent = {
23
+ platform: proto.ClientPayload.UserAgent.Platform.ANDROID,
24
+ releaseChannel: proto.ClientPayload.UserAgent.ReleaseChannel.RELEASE,
25
+ appVersion: version,
26
+ mcc: info.mcc ?? '000',
27
+ mnc: info.mnc ?? '000',
28
+ osVersion: info.osVersion,
29
+ manufacturer: info.manufacturer,
30
+ device: info.device,
31
+ osBuildNumber: info.osBuildNumber,
32
+ phoneId: info.phoneId ?? randomUUID(),
33
+ localeLanguageIso6391: info.localeLanguageIso6391 ?? 'en',
34
+ localeCountryIso31661Alpha2: info.localeCountryIso31661Alpha2 ?? 'US',
35
+ deviceType: proto.ClientPayload.UserAgent.DeviceType.PHONE,
36
+ deviceBoard: info.deviceBoard,
37
+ deviceModelType: info.deviceModelType
38
+ };
39
+ return proto.ClientPayload.encode({
40
+ passive: config.passive === true,
41
+ pull: config.pull ?? true,
42
+ product: proto.ClientPayload.Product.WHATSAPP,
43
+ connectType: config.connectType ?? proto.ClientPayload.ConnectType.CELLULAR_UNKNOWN,
44
+ connectReason: config.connectReason ?? proto.ClientPayload.ConnectReason.USER_ACTIVATED,
45
+ userAgent,
46
+ username: config.username,
47
+ device: config.device ?? 0,
48
+ lidDbMigrated: config.lidDbMigrated === true,
49
+ pushName: config.pushName,
50
+ yearClass: config.yearClass,
51
+ memClass: config.memClass
52
+ }).finish();
53
+ }