zapo-js 0.1.1 → 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 (589) hide show
  1. package/README.md +20 -4
  2. package/dist/appstate/WaAppStateCrypto.js +19 -26
  3. package/dist/appstate/WaAppStateSyncClient.js +293 -181
  4. package/dist/appstate/WaAppStateSyncResponseParser.js +16 -5
  5. package/dist/appstate/constants.js +4 -3
  6. package/dist/appstate/{store/sqlite.js → encoding.js} +13 -8
  7. package/dist/appstate/index.js +8 -6
  8. package/dist/appstate/utils.js +9 -34
  9. package/dist/auth/WaAuthClient.js +43 -61
  10. package/dist/auth/flow/WaAuthCredentialsFlow.js +22 -15
  11. package/dist/auth/index.js +1 -8
  12. package/dist/auth/pairing/WaPairingCodeCrypto.js +6 -4
  13. package/dist/auth/pairing/WaPairingFlow.js +34 -26
  14. package/dist/auth/pairing/WaQrFlow.js +37 -24
  15. package/dist/client/WaClient.js +275 -324
  16. package/dist/client/WaClientFactory.js +500 -133
  17. package/dist/client/connection/WaConnectionManager.js +301 -0
  18. package/dist/client/connection/WaKeyShareCoordinator.js +63 -0
  19. package/dist/client/connection/WaReceiptQueue.js +51 -0
  20. package/dist/client/coordinators/WaAppStateMutationCoordinator.js +471 -0
  21. package/dist/client/coordinators/WaBusinessCoordinator.js +241 -0
  22. package/dist/client/coordinators/WaGroupCoordinator.js +30 -16
  23. package/dist/client/coordinators/WaIncomingNodeCoordinator.js +21 -27
  24. package/dist/client/coordinators/WaMessageDispatchCoordinator.js +439 -701
  25. package/dist/client/coordinators/WaPassiveTasksCoordinator.js +74 -31
  26. package/dist/client/coordinators/WaPrivacyCoordinator.js +134 -0
  27. package/dist/client/coordinators/WaProfileCoordinator.js +212 -0
  28. package/dist/client/coordinators/WaRetryCoordinator.js +242 -57
  29. package/dist/client/coordinators/WaStreamControlCoordinator.js +18 -11
  30. package/dist/client/coordinators/WaTrustedContactTokenCoordinator.js +166 -0
  31. package/dist/client/dirty.js +74 -48
  32. package/dist/client/events/chat.js +4 -3
  33. package/dist/client/events/devices.js +72 -0
  34. package/dist/client/events/group.js +62 -47
  35. package/dist/client/events/identity.js +22 -0
  36. package/dist/client/events/privacy-token.js +39 -0
  37. package/dist/client/history-sync.js +94 -63
  38. package/dist/client/incoming.js +60 -27
  39. package/dist/client/mailbox.js +24 -23
  40. package/dist/client/messages.js +107 -31
  41. package/dist/client/messaging/fanout.js +199 -0
  42. package/dist/client/messaging/key-protocol.js +130 -0
  43. package/dist/client/messaging/participants.js +193 -0
  44. package/dist/client/persistence/WriteBehindPersistence.js +129 -0
  45. package/dist/client/tokens/cs-token.js +50 -0
  46. package/dist/client/tokens/tc-token.js +25 -0
  47. package/dist/crypto/core/hkdf.js +3 -8
  48. package/dist/crypto/core/index.js +2 -5
  49. package/dist/crypto/core/keys.js +6 -7
  50. package/dist/crypto/core/nonce.js +2 -0
  51. package/dist/crypto/core/primitives.js +12 -23
  52. package/dist/crypto/core/random.js +26 -23
  53. package/dist/crypto/curves/Ed25519.js +7 -8
  54. package/dist/crypto/curves/X25519.js +38 -22
  55. package/dist/crypto/index.js +1 -3
  56. package/dist/crypto/math/constants.js +13 -36
  57. package/dist/crypto/math/edwards.js +171 -44
  58. package/dist/crypto/math/fe.js +706 -0
  59. package/dist/crypto/math/mod.js +10 -3
  60. package/dist/esm/appstate/WaAppStateCrypto.js +7 -14
  61. package/dist/esm/appstate/WaAppStateSyncClient.js +284 -172
  62. package/dist/esm/appstate/WaAppStateSyncResponseParser.js +17 -6
  63. package/dist/esm/appstate/constants.js +3 -2
  64. package/dist/esm/appstate/{store/sqlite.js → encoding.js} +13 -8
  65. package/dist/esm/appstate/index.js +2 -2
  66. package/dist/esm/appstate/utils.js +8 -30
  67. package/dist/esm/auth/WaAuthClient.js +43 -61
  68. package/dist/esm/auth/flow/WaAuthCredentialsFlow.js +22 -15
  69. package/dist/esm/auth/index.js +0 -3
  70. package/dist/esm/auth/pairing/WaPairingCodeCrypto.js +6 -4
  71. package/dist/esm/auth/pairing/WaPairingFlow.js +28 -20
  72. package/dist/esm/auth/pairing/WaQrFlow.js +37 -24
  73. package/dist/esm/client/WaClient.js +275 -324
  74. package/dist/esm/client/WaClientFactory.js +501 -134
  75. package/dist/esm/client/connection/WaConnectionManager.js +297 -0
  76. package/dist/esm/client/connection/WaKeyShareCoordinator.js +59 -0
  77. package/dist/esm/client/connection/WaReceiptQueue.js +47 -0
  78. package/dist/esm/client/coordinators/WaAppStateMutationCoordinator.js +467 -0
  79. package/dist/esm/client/coordinators/WaBusinessCoordinator.js +238 -0
  80. package/dist/esm/client/coordinators/WaGroupCoordinator.js +23 -9
  81. package/dist/esm/client/coordinators/WaIncomingNodeCoordinator.js +21 -27
  82. package/dist/esm/client/coordinators/WaMessageDispatchCoordinator.js +443 -705
  83. package/dist/esm/client/coordinators/WaPassiveTasksCoordinator.js +74 -31
  84. package/dist/esm/client/coordinators/WaPrivacyCoordinator.js +131 -0
  85. package/dist/esm/client/coordinators/WaProfileCoordinator.js +209 -0
  86. package/dist/esm/client/coordinators/WaRetryCoordinator.js +244 -59
  87. package/dist/esm/client/coordinators/WaStreamControlCoordinator.js +19 -12
  88. package/dist/esm/client/coordinators/WaTrustedContactTokenCoordinator.js +162 -0
  89. package/dist/esm/client/dirty.js +69 -43
  90. package/dist/esm/client/events/chat.js +4 -3
  91. package/dist/esm/client/events/devices.js +68 -0
  92. package/dist/esm/client/events/group.js +53 -39
  93. package/dist/esm/client/events/identity.js +19 -0
  94. package/dist/esm/client/events/privacy-token.js +36 -0
  95. package/dist/esm/client/history-sync.js +91 -60
  96. package/dist/esm/client/incoming.js +61 -28
  97. package/dist/esm/client/mailbox.js +24 -23
  98. package/dist/esm/client/messages.js +108 -32
  99. package/dist/esm/client/messaging/fanout.js +196 -0
  100. package/dist/esm/client/messaging/key-protocol.js +127 -0
  101. package/dist/esm/client/messaging/participants.js +190 -0
  102. package/dist/esm/client/persistence/WriteBehindPersistence.js +125 -0
  103. package/dist/esm/client/tokens/cs-token.js +46 -0
  104. package/dist/esm/client/tokens/tc-token.js +18 -0
  105. package/dist/esm/crypto/core/hkdf.js +3 -8
  106. package/dist/esm/crypto/core/index.js +2 -3
  107. package/dist/esm/crypto/core/keys.js +3 -4
  108. package/dist/esm/crypto/core/nonce.js +2 -0
  109. package/dist/esm/crypto/core/primitives.js +12 -22
  110. package/dist/esm/crypto/core/random.js +25 -23
  111. package/dist/esm/crypto/curves/Ed25519.js +4 -5
  112. package/dist/esm/crypto/curves/X25519.js +35 -19
  113. package/dist/esm/crypto/index.js +0 -1
  114. package/dist/esm/crypto/math/constants.js +12 -35
  115. package/dist/esm/crypto/math/edwards.js +174 -47
  116. package/dist/esm/crypto/math/fe.js +691 -0
  117. package/dist/esm/crypto/math/mod.js +10 -1
  118. package/dist/esm/index.js +1 -1
  119. package/dist/esm/infra/log/ConsoleLogger.js +18 -17
  120. package/dist/esm/infra/log/PinoLogger.js +15 -9
  121. package/dist/esm/infra/log/types.js +11 -1
  122. package/dist/esm/infra/perf/BackgroundQueue.js +478 -0
  123. package/dist/esm/infra/perf/BoundedTaskQueue.js +16 -18
  124. package/dist/esm/infra/perf/PromiseDedup.js +20 -0
  125. package/dist/esm/infra/perf/SharedExclusiveGate.js +109 -0
  126. package/dist/esm/infra/perf/StoreLock.js +77 -0
  127. package/dist/esm/media/WaMediaCrypto.js +96 -16
  128. package/dist/esm/media/WaMediaTransferClient.js +251 -91
  129. package/dist/esm/media/conn.js +10 -6
  130. package/dist/esm/media/constants.js +6 -2
  131. package/dist/esm/message/WaMessageClient.js +30 -32
  132. package/dist/esm/message/ack.js +6 -6
  133. package/dist/esm/message/addon-crypto.js +59 -0
  134. package/dist/esm/message/content.js +195 -9
  135. package/dist/esm/message/icdc.js +76 -0
  136. package/dist/esm/message/incoming.js +129 -122
  137. package/dist/esm/message/index.js +2 -0
  138. package/dist/esm/message/phash.js +3 -1
  139. package/dist/esm/message/reporting-token.js +425 -0
  140. package/dist/esm/message/use-case-secret.js +49 -0
  141. package/dist/esm/protocol/appstate.js +27 -0
  142. package/dist/esm/protocol/browser.js +10 -18
  143. package/dist/esm/protocol/constants.js +6 -3
  144. package/dist/esm/protocol/defaults.js +6 -0
  145. package/dist/esm/protocol/index.js +2 -11
  146. package/dist/esm/protocol/jid.js +133 -52
  147. package/dist/esm/protocol/media.js +3 -3
  148. package/dist/esm/protocol/message.js +61 -1
  149. package/dist/esm/protocol/nodes.js +4 -0
  150. package/dist/esm/protocol/notification.js +3 -1
  151. package/dist/esm/protocol/privacy-token.js +17 -0
  152. package/dist/esm/protocol/privacy.js +55 -0
  153. package/dist/esm/protocol/stream.js +26 -1
  154. package/dist/esm/protocol/usync.js +11 -0
  155. package/dist/esm/retry/codec.js +216 -0
  156. package/dist/esm/retry/constants.js +1 -1
  157. package/dist/esm/retry/index.js +3 -2
  158. package/dist/esm/retry/parse.js +88 -86
  159. package/dist/esm/retry/replay.js +54 -51
  160. package/dist/esm/retry/tracker.js +94 -0
  161. package/dist/esm/signal/api/SignalDeviceSyncApi.js +276 -92
  162. package/dist/esm/signal/api/SignalDigestSyncApi.js +17 -8
  163. package/dist/esm/signal/api/SignalIdentitySyncApi.js +67 -37
  164. package/dist/esm/signal/api/SignalMissingPreKeysSyncApi.js +86 -67
  165. package/dist/esm/signal/api/SignalRotateKeyApi.js +4 -2
  166. package/dist/esm/signal/api/SignalSessionSyncApi.js +36 -34
  167. package/dist/esm/signal/api/result-map.js +10 -0
  168. package/dist/esm/signal/constants.js +0 -4
  169. package/dist/esm/signal/crypto/WaAdvSignature.js +13 -9
  170. package/dist/esm/signal/{store/sqlite.js → encoding.js} +93 -60
  171. package/dist/esm/signal/group/SenderKeyChain.js +28 -23
  172. package/dist/esm/signal/group/SenderKeyCodec.js +5 -6
  173. package/dist/esm/signal/group/SenderKeyManager.js +144 -115
  174. package/dist/esm/signal/index.js +2 -0
  175. package/dist/esm/signal/registration/keygen.js +6 -2
  176. package/dist/esm/signal/registration/utils.js +1 -0
  177. package/dist/esm/signal/session/SignalProtocol.js +164 -53
  178. package/dist/esm/signal/session/SignalRatchet.js +24 -15
  179. package/dist/esm/signal/session/SignalSession.js +14 -9
  180. package/dist/esm/signal/session/resolver.js +221 -0
  181. package/dist/esm/store/contracts/privacy-token.store.js +1 -0
  182. package/dist/esm/store/createStore.js +100 -188
  183. package/dist/esm/store/index.js +1 -10
  184. package/dist/esm/store/locks/appstate.lock.js +26 -0
  185. package/dist/esm/store/locks/auth.lock.js +15 -0
  186. package/dist/esm/store/locks/contact.lock.js +20 -0
  187. package/dist/esm/store/locks/device-list.lock.js +20 -0
  188. package/dist/esm/store/locks/message.lock.js +21 -0
  189. package/dist/esm/store/locks/participants.lock.js +20 -0
  190. package/dist/esm/store/locks/privacy-token.lock.js +18 -0
  191. package/dist/esm/store/locks/retry.lock.js +29 -0
  192. package/dist/esm/store/locks/sender-key.lock.js +52 -0
  193. package/dist/esm/store/locks/signal.lock.js +63 -0
  194. package/dist/esm/store/locks/thread.lock.js +21 -0
  195. package/dist/esm/store/noop.store.js +4 -7
  196. package/dist/esm/store/providers/memory/appstate.store.js +38 -16
  197. package/dist/esm/store/providers/memory/contact.store.js +5 -0
  198. package/dist/esm/store/providers/memory/device-list.store.js +12 -34
  199. package/dist/esm/store/providers/memory/message.store.js +11 -5
  200. package/dist/esm/store/providers/memory/participants.store.js +1 -8
  201. package/dist/esm/store/providers/memory/privacy-token.store.js +43 -0
  202. package/dist/esm/store/providers/memory/retry.store.js +77 -2
  203. package/dist/esm/store/providers/memory/sender-key.store.js +11 -8
  204. package/dist/esm/store/providers/memory/signal.store.js +47 -18
  205. package/dist/esm/store/providers/memory/thread.store.js +5 -0
  206. package/dist/esm/transport/WaComms.js +28 -24
  207. package/dist/esm/transport/WaWebSocket.js +115 -18
  208. package/dist/esm/transport/binary/constants.js +0 -30
  209. package/dist/esm/transport/binary/decoder.js +8 -8
  210. package/dist/esm/transport/binary/encoder.js +10 -9
  211. package/dist/esm/transport/binary/index.js +0 -1
  212. package/dist/esm/transport/index.js +1 -0
  213. package/dist/esm/transport/keepalive/WaKeepAlive.js +2 -8
  214. package/dist/esm/transport/node/WaNodeOrchestrator.js +25 -21
  215. package/dist/esm/transport/node/WaNodeTransport.js +0 -3
  216. package/dist/esm/transport/node/builders/{accountSync.js → account-sync.js} +16 -36
  217. package/dist/esm/transport/node/builders/business.js +129 -0
  218. package/dist/esm/transport/node/builders/global.js +370 -0
  219. package/dist/esm/transport/node/builders/index.js +7 -3
  220. package/dist/esm/transport/node/builders/message.js +63 -230
  221. package/dist/esm/transport/node/builders/pairing.js +2 -27
  222. package/dist/esm/transport/node/builders/privacy-token.js +41 -0
  223. package/dist/esm/transport/node/builders/privacy.js +48 -0
  224. package/dist/esm/transport/node/builders/profile.js +70 -0
  225. package/dist/esm/transport/node/builders/retry.js +10 -22
  226. package/dist/esm/transport/node/builders/usync.js +45 -0
  227. package/dist/esm/transport/node/helpers.js +125 -5
  228. package/dist/esm/transport/node/usync.js +5 -0
  229. package/dist/esm/transport/node/xml.js +35 -14
  230. package/dist/esm/transport/noise/WaClientPayload.js +10 -10
  231. package/dist/esm/transport/noise/WaFrameCodec.js +48 -33
  232. package/dist/esm/transport/noise/WaNoiseCert.js +4 -7
  233. package/dist/esm/transport/noise/WaNoiseSession.js +77 -29
  234. package/dist/esm/transport/noise/WaNoiseSocket.js +8 -4
  235. package/dist/esm/transport/proxy.js +27 -0
  236. package/dist/esm/transport/stream/parse.js +17 -48
  237. package/dist/esm/util/bytes.js +67 -45
  238. package/dist/esm/util/coercion.js +6 -14
  239. package/dist/esm/util/index.js +5 -0
  240. package/dist/esm/util/primitives.js +40 -14
  241. package/dist/index.js +7 -1
  242. package/dist/infra/log/ConsoleLogger.js +18 -17
  243. package/dist/infra/log/PinoLogger.js +15 -9
  244. package/dist/infra/log/types.js +12 -0
  245. package/dist/infra/perf/BackgroundQueue.js +482 -0
  246. package/dist/infra/perf/BoundedTaskQueue.js +16 -18
  247. package/dist/infra/perf/PromiseDedup.js +24 -0
  248. package/dist/infra/perf/SharedExclusiveGate.js +113 -0
  249. package/dist/infra/perf/StoreLock.js +81 -0
  250. package/dist/media/WaMediaCrypto.js +95 -15
  251. package/dist/media/WaMediaTransferClient.js +284 -91
  252. package/dist/media/conn.js +10 -6
  253. package/dist/media/constants.js +6 -2
  254. package/dist/message/WaMessageClient.js +31 -33
  255. package/dist/message/ack.js +6 -6
  256. package/dist/message/addon-crypto.js +65 -0
  257. package/dist/message/content.js +198 -9
  258. package/dist/message/icdc.js +81 -0
  259. package/dist/message/incoming.js +127 -120
  260. package/dist/message/index.js +2 -0
  261. package/dist/message/phash.js +3 -1
  262. package/dist/message/reporting-token.js +429 -0
  263. package/dist/message/use-case-secret.js +55 -0
  264. package/dist/protocol/appstate.js +28 -1
  265. package/dist/protocol/browser.js +10 -18
  266. package/dist/protocol/constants.js +26 -1
  267. package/dist/protocol/defaults.js +6 -0
  268. package/dist/protocol/index.js +23 -42
  269. package/dist/protocol/jid.js +140 -52
  270. package/dist/protocol/media.js +3 -3
  271. package/dist/protocol/message.js +62 -2
  272. package/dist/protocol/nodes.js +4 -0
  273. package/dist/protocol/notification.js +3 -1
  274. package/dist/protocol/privacy-token.js +20 -0
  275. package/dist/protocol/privacy.js +58 -0
  276. package/dist/protocol/stream.js +27 -2
  277. package/dist/protocol/usync.js +14 -0
  278. package/dist/retry/codec.js +220 -0
  279. package/dist/retry/constants.js +1 -1
  280. package/dist/retry/index.js +7 -5
  281. package/dist/retry/parse.js +88 -85
  282. package/dist/retry/replay.js +52 -49
  283. package/dist/retry/tracker.js +97 -0
  284. package/dist/signal/api/SignalDeviceSyncApi.js +273 -89
  285. package/dist/signal/api/SignalDigestSyncApi.js +17 -8
  286. package/dist/signal/api/SignalIdentitySyncApi.js +66 -36
  287. package/dist/signal/api/SignalMissingPreKeysSyncApi.js +82 -63
  288. package/dist/signal/api/SignalRotateKeyApi.js +4 -2
  289. package/dist/signal/api/SignalSessionSyncApi.js +36 -34
  290. package/dist/signal/api/result-map.js +13 -0
  291. package/dist/signal/constants.js +1 -5
  292. package/dist/signal/crypto/WaAdvSignature.js +11 -7
  293. package/dist/signal/{store/sqlite.js → encoding.js} +94 -61
  294. package/dist/signal/group/SenderKeyChain.js +27 -22
  295. package/dist/signal/group/SenderKeyCodec.js +5 -6
  296. package/dist/signal/group/SenderKeyManager.js +144 -115
  297. package/dist/signal/index.js +15 -1
  298. package/dist/signal/registration/keygen.js +6 -2
  299. package/dist/signal/registration/utils.js +1 -0
  300. package/dist/signal/session/SignalProtocol.js +164 -53
  301. package/dist/signal/session/SignalRatchet.js +24 -15
  302. package/dist/signal/session/SignalSession.js +14 -9
  303. package/dist/signal/session/resolver.js +224 -0
  304. package/dist/store/contracts/privacy-token.store.js +2 -0
  305. package/dist/store/createStore.js +100 -188
  306. package/dist/store/index.js +15 -33
  307. package/dist/store/locks/appstate.lock.js +29 -0
  308. package/dist/store/locks/auth.lock.js +18 -0
  309. package/dist/store/locks/contact.lock.js +23 -0
  310. package/dist/store/locks/device-list.lock.js +23 -0
  311. package/dist/store/locks/message.lock.js +24 -0
  312. package/dist/store/locks/participants.lock.js +23 -0
  313. package/dist/store/locks/privacy-token.lock.js +21 -0
  314. package/dist/store/locks/retry.lock.js +32 -0
  315. package/dist/store/locks/sender-key.lock.js +55 -0
  316. package/dist/store/locks/signal.lock.js +66 -0
  317. package/dist/store/locks/thread.lock.js +24 -0
  318. package/dist/store/noop.store.js +4 -7
  319. package/dist/store/providers/memory/appstate.store.js +36 -14
  320. package/dist/store/providers/memory/contact.store.js +5 -0
  321. package/dist/store/providers/memory/device-list.store.js +12 -34
  322. package/dist/store/providers/memory/message.store.js +11 -5
  323. package/dist/store/providers/memory/participants.store.js +1 -8
  324. package/dist/store/providers/memory/privacy-token.store.js +47 -0
  325. package/dist/store/providers/memory/retry.store.js +77 -2
  326. package/dist/store/providers/memory/sender-key.store.js +14 -11
  327. package/dist/store/providers/memory/signal.store.js +54 -25
  328. package/dist/store/providers/memory/thread.store.js +5 -0
  329. package/dist/transport/WaComms.js +30 -26
  330. package/dist/transport/WaWebSocket.js +148 -18
  331. package/dist/transport/binary/constants.js +1 -31
  332. package/dist/transport/binary/decoder.js +8 -8
  333. package/dist/transport/binary/encoder.js +10 -9
  334. package/dist/transport/binary/index.js +0 -4
  335. package/dist/transport/index.js +7 -1
  336. package/dist/transport/keepalive/WaKeepAlive.js +1 -7
  337. package/dist/transport/node/WaNodeOrchestrator.js +25 -21
  338. package/dist/transport/node/WaNodeTransport.js +0 -3
  339. package/dist/transport/node/builders/{accountSync.js → account-sync.js} +15 -35
  340. package/dist/transport/node/builders/business.js +137 -0
  341. package/dist/transport/node/builders/global.js +375 -0
  342. package/dist/transport/node/builders/index.js +29 -17
  343. package/dist/transport/node/builders/message.js +64 -236
  344. package/dist/transport/node/builders/pairing.js +2 -29
  345. package/dist/transport/node/builders/privacy-token.js +46 -0
  346. package/dist/transport/node/builders/privacy.js +55 -0
  347. package/dist/transport/node/builders/profile.js +78 -0
  348. package/dist/transport/node/builders/retry.js +9 -21
  349. package/dist/transport/node/builders/usync.js +49 -0
  350. package/dist/transport/node/helpers.js +131 -4
  351. package/dist/transport/node/usync.js +8 -0
  352. package/dist/transport/node/xml.js +35 -14
  353. package/dist/transport/noise/WaClientPayload.js +13 -13
  354. package/dist/transport/noise/WaFrameCodec.js +47 -32
  355. package/dist/transport/noise/WaNoiseCert.js +5 -8
  356. package/dist/transport/noise/WaNoiseSession.js +77 -29
  357. package/dist/transport/noise/WaNoiseSocket.js +8 -4
  358. package/dist/transport/proxy.js +34 -0
  359. package/dist/transport/stream/parse.js +20 -52
  360. package/dist/types/appstate/WaAppStateCrypto.d.ts +0 -1
  361. package/dist/types/appstate/WaAppStateSyncClient.d.ts +5 -2
  362. package/dist/types/appstate/constants.d.ts +1 -0
  363. package/dist/types/appstate/encoding.d.ts +7 -0
  364. package/dist/types/appstate/index.d.ts +3 -3
  365. package/dist/types/appstate/utils.d.ts +0 -3
  366. package/dist/types/auth/WaAuthClient.d.ts +10 -12
  367. package/dist/types/auth/flow/WaAuthCredentialsFlow.d.ts +1 -1
  368. package/dist/types/auth/index.d.ts +0 -4
  369. package/dist/types/auth/pairing/WaQrFlow.d.ts +1 -1
  370. package/dist/types/auth/types.d.ts +7 -9
  371. package/dist/types/client/WaClient.d.ts +42 -25
  372. package/dist/types/client/WaClientFactory.d.ts +33 -26
  373. package/dist/types/client/connection/WaConnectionManager.d.ts +66 -0
  374. package/dist/types/client/connection/WaKeyShareCoordinator.d.ts +14 -0
  375. package/dist/types/client/connection/WaReceiptQueue.d.ts +13 -0
  376. package/dist/types/client/coordinators/WaAppStateMutationCoordinator.d.ts +46 -0
  377. package/dist/types/client/coordinators/WaBusinessCoordinator.d.ts +57 -0
  378. package/dist/types/client/coordinators/WaIncomingNodeCoordinator.d.ts +3 -2
  379. package/dist/types/client/coordinators/WaMessageDispatchCoordinator.d.ts +29 -38
  380. package/dist/types/client/coordinators/WaPassiveTasksCoordinator.d.ts +4 -0
  381. package/dist/types/client/coordinators/WaPrivacyCoordinator.d.ts +26 -0
  382. package/dist/types/client/coordinators/WaProfileCoordinator.d.ts +36 -0
  383. package/dist/types/client/coordinators/WaRetryCoordinator.d.ts +8 -0
  384. package/dist/types/client/coordinators/WaStreamControlCoordinator.d.ts +3 -2
  385. package/dist/types/client/coordinators/WaTrustedContactTokenCoordinator.d.ts +45 -0
  386. package/dist/types/client/dirty.d.ts +1 -0
  387. package/dist/types/client/events/devices.d.ts +20 -0
  388. package/dist/types/client/events/group.d.ts +2 -1
  389. package/dist/types/client/events/identity.d.ts +9 -0
  390. package/dist/types/client/events/privacy-token.d.ts +7 -0
  391. package/dist/types/client/history-sync.d.ts +9 -6
  392. package/dist/types/client/incoming.d.ts +3 -1
  393. package/dist/types/client/index.d.ts +1 -1
  394. package/dist/types/client/mailbox.d.ts +3 -5
  395. package/dist/types/client/messages.d.ts +1 -2
  396. package/dist/types/client/messaging/fanout.d.ts +14 -0
  397. package/dist/types/client/messaging/key-protocol.d.ts +18 -0
  398. package/dist/types/client/messaging/participants.d.ts +13 -0
  399. package/dist/types/client/persistence/WriteBehindPersistence.d.ts +34 -0
  400. package/dist/types/client/tokens/cs-token.d.ts +10 -0
  401. package/dist/types/client/tokens/tc-token.d.ts +5 -0
  402. package/dist/types/client/types.d.ts +75 -4
  403. package/dist/types/crypto/core/hkdf.d.ts +0 -6
  404. package/dist/types/crypto/core/index.d.ts +2 -3
  405. package/dist/types/crypto/core/nonce.d.ts +2 -0
  406. package/dist/types/crypto/core/primitives.d.ts +0 -1
  407. package/dist/types/crypto/core/random.d.ts +2 -7
  408. package/dist/types/crypto/index.d.ts +0 -1
  409. package/dist/types/crypto/math/constants.d.ts +4 -2
  410. package/dist/types/crypto/math/fe.d.ts +30 -0
  411. package/dist/types/crypto/math/mod.d.ts +0 -2
  412. package/dist/types/crypto/math/types.d.ts +11 -4
  413. package/dist/types/index.d.ts +5 -3
  414. package/dist/types/infra/log/ConsoleLogger.d.ts +2 -1
  415. package/dist/types/infra/log/PinoLogger.d.ts +1 -1
  416. package/dist/types/infra/log/types.d.ts +1 -0
  417. package/dist/types/infra/perf/BackgroundQueue.d.ts +58 -0
  418. package/dist/types/infra/perf/BoundedTaskQueue.d.ts +1 -1
  419. package/dist/types/infra/perf/PromiseDedup.d.ts +4 -0
  420. package/dist/types/infra/perf/SharedExclusiveGate.d.ts +17 -0
  421. package/dist/types/infra/perf/StoreLock.d.ts +10 -0
  422. package/dist/types/media/WaMediaCrypto.d.ts +3 -2
  423. package/dist/types/media/WaMediaTransferClient.d.ts +16 -15
  424. package/dist/types/media/constants.d.ts +1 -1
  425. package/dist/types/media/index.d.ts +1 -1
  426. package/dist/types/media/types.d.ts +15 -2
  427. package/dist/types/message/addon-crypto.d.ts +25 -0
  428. package/dist/types/message/content.d.ts +8 -0
  429. package/dist/types/message/icdc.d.ts +13 -0
  430. package/dist/types/message/index.d.ts +2 -0
  431. package/dist/types/message/reporting-token.d.ts +18 -0
  432. package/dist/types/message/types.d.ts +45 -6
  433. package/dist/types/message/use-case-secret.d.ts +20 -0
  434. package/dist/types/protocol/appstate.d.ts +47 -0
  435. package/dist/types/protocol/constants.d.ts +8 -3
  436. package/dist/types/protocol/defaults.d.ts +6 -0
  437. package/dist/types/protocol/index.d.ts +2 -11
  438. package/dist/types/protocol/jid.d.ts +22 -5
  439. package/dist/types/protocol/message.d.ts +60 -0
  440. package/dist/types/protocol/nodes.d.ts +4 -0
  441. package/dist/types/protocol/notification.d.ts +2 -0
  442. package/dist/types/protocol/privacy-token.d.ts +17 -0
  443. package/dist/types/protocol/privacy.d.ts +75 -0
  444. package/dist/types/protocol/stream.d.ts +30 -0
  445. package/dist/types/protocol/usync.d.ts +11 -0
  446. package/dist/types/retry/codec.d.ts +3 -0
  447. package/dist/types/retry/index.d.ts +4 -3
  448. package/dist/types/retry/parse.d.ts +5 -2
  449. package/dist/types/retry/replay.d.ts +0 -4
  450. package/dist/types/retry/tracker.d.ts +20 -0
  451. package/dist/types/retry/types.d.ts +10 -4
  452. package/dist/types/signal/api/SignalDeviceSyncApi.d.ts +15 -2
  453. package/dist/types/signal/api/SignalDigestSyncApi.d.ts +6 -0
  454. package/dist/types/signal/api/SignalIdentitySyncApi.d.ts +2 -0
  455. package/dist/types/signal/api/SignalRotateKeyApi.d.ts +4 -5
  456. package/dist/types/signal/api/SignalSessionSyncApi.d.ts +8 -6
  457. package/dist/types/signal/api/result-map.d.ts +1 -0
  458. package/dist/types/signal/constants.d.ts +0 -3
  459. package/dist/types/signal/{store/sqlite.d.ts → encoding.d.ts} +3 -3
  460. package/dist/types/signal/group/SenderKeyCodec.d.ts +4 -6
  461. package/dist/types/signal/group/SenderKeyManager.d.ts +10 -5
  462. package/dist/types/signal/index.d.ts +3 -0
  463. package/dist/types/signal/session/SignalProtocol.d.ts +19 -4
  464. package/dist/types/signal/session/resolver.d.ts +22 -0
  465. package/dist/types/store/contracts/appstate.store.d.ts +4 -1
  466. package/dist/types/store/contracts/contact.store.d.ts +1 -0
  467. package/dist/types/store/contracts/device-list.store.d.ts +0 -3
  468. package/dist/types/store/contracts/message.store.d.ts +1 -0
  469. package/dist/types/store/contracts/participants.store.d.ts +0 -1
  470. package/dist/types/store/contracts/privacy-token.store.d.ts +16 -0
  471. package/dist/types/store/contracts/retry.store.d.ts +7 -0
  472. package/dist/types/store/contracts/sender-key.store.d.ts +0 -1
  473. package/dist/types/store/contracts/signal.store.d.ts +13 -0
  474. package/dist/types/store/contracts/thread.store.d.ts +1 -0
  475. package/dist/types/store/createStore.d.ts +1 -1
  476. package/dist/types/store/index.d.ts +5 -13
  477. package/dist/types/store/locks/appstate.lock.d.ts +3 -0
  478. package/dist/types/store/locks/auth.lock.d.ts +3 -0
  479. package/dist/types/store/locks/contact.lock.d.ts +3 -0
  480. package/dist/types/store/locks/device-list.lock.d.ts +2 -0
  481. package/dist/types/store/locks/message.lock.d.ts +3 -0
  482. package/dist/types/store/locks/participants.lock.d.ts +2 -0
  483. package/dist/types/store/locks/privacy-token.lock.d.ts +2 -0
  484. package/dist/types/store/locks/retry.lock.d.ts +2 -0
  485. package/dist/types/store/locks/sender-key.lock.d.ts +3 -0
  486. package/dist/types/store/locks/signal.lock.d.ts +3 -0
  487. package/dist/types/store/locks/thread.lock.d.ts +3 -0
  488. package/dist/types/store/providers/memory/appstate.store.d.ts +3 -1
  489. package/dist/types/store/providers/memory/contact.store.d.ts +1 -0
  490. package/dist/types/store/providers/memory/device-list.store.d.ts +0 -3
  491. package/dist/types/store/providers/memory/message.store.d.ts +1 -0
  492. package/dist/types/store/providers/memory/participants.store.d.ts +0 -1
  493. package/dist/types/store/providers/memory/privacy-token.store.d.ts +13 -0
  494. package/dist/types/store/providers/memory/retry.store.d.ts +8 -0
  495. package/dist/types/store/providers/memory/sender-key.store.d.ts +0 -1
  496. package/dist/types/store/providers/memory/signal.store.d.ts +8 -1
  497. package/dist/types/store/providers/memory/thread.store.d.ts +1 -0
  498. package/dist/types/store/types.d.ts +49 -58
  499. package/dist/types/transport/WaWebSocket.d.ts +3 -1
  500. package/dist/types/transport/binary/constants.d.ts +0 -30
  501. package/dist/types/transport/binary/index.d.ts +0 -1
  502. package/dist/types/transport/index.d.ts +2 -1
  503. package/dist/types/transport/keepalive/WaKeepAlive.d.ts +0 -1
  504. package/dist/types/transport/node/WaNodeOrchestrator.d.ts +3 -4
  505. package/dist/types/transport/node/WaNodeTransport.d.ts +0 -9
  506. package/dist/types/transport/node/builders/business.d.ts +29 -0
  507. package/dist/types/transport/node/builders/global.d.ts +102 -0
  508. package/dist/types/transport/node/builders/group.d.ts +4 -6
  509. package/dist/types/transport/node/builders/index.d.ts +7 -3
  510. package/dist/types/transport/node/builders/message.d.ts +20 -30
  511. package/dist/types/transport/node/builders/pairing.d.ts +0 -2
  512. package/dist/types/transport/node/builders/privacy-token.d.ts +9 -0
  513. package/dist/types/transport/node/builders/privacy.d.ts +7 -0
  514. package/dist/types/transport/node/builders/profile.d.ts +8 -0
  515. package/dist/types/transport/node/builders/retry.d.ts +2 -5
  516. package/dist/types/transport/node/builders/usync.d.ts +21 -0
  517. package/dist/types/transport/node/helpers.d.ts +13 -0
  518. package/dist/types/transport/node/usync.d.ts +2 -0
  519. package/dist/types/transport/noise/WaFrameCodec.d.ts +3 -0
  520. package/dist/types/transport/noise/WaNoiseSession.d.ts +4 -2
  521. package/dist/types/transport/noise/WaNoiseSocket.d.ts +4 -2
  522. package/dist/types/transport/proxy.d.ts +6 -0
  523. package/dist/types/transport/stream/parse.d.ts +0 -1
  524. package/dist/types/transport/types.d.ts +18 -1
  525. package/dist/types/util/bytes.d.ts +5 -0
  526. package/dist/types/util/index.d.ts +5 -0
  527. package/dist/types/util/primitives.d.ts +2 -0
  528. package/dist/util/bytes.js +72 -46
  529. package/dist/util/coercion.js +6 -14
  530. package/dist/util/index.js +23 -0
  531. package/dist/util/primitives.js +42 -14
  532. package/package.json +52 -9
  533. package/proto/index.js +1 -1
  534. package/dist/crypto/core/constants.js +0 -4
  535. package/dist/crypto/core/encoding.js +0 -29
  536. package/dist/esm/crypto/core/constants.js +0 -1
  537. package/dist/esm/crypto/core/encoding.js +0 -25
  538. package/dist/esm/retry/outbound.js +0 -83
  539. package/dist/esm/store/providers/sqlite/BaseSqliteStore.js +0 -37
  540. package/dist/esm/store/providers/sqlite/appstate.store.js +0 -169
  541. package/dist/esm/store/providers/sqlite/auth.store.js +0 -176
  542. package/dist/esm/store/providers/sqlite/connection.js +0 -240
  543. package/dist/esm/store/providers/sqlite/contact.store.js +0 -61
  544. package/dist/esm/store/providers/sqlite/device-list.store.js +0 -155
  545. package/dist/esm/store/providers/sqlite/message.store.js +0 -119
  546. package/dist/esm/store/providers/sqlite/migrations.js +0 -347
  547. package/dist/esm/store/providers/sqlite/participants.store.js +0 -85
  548. package/dist/esm/store/providers/sqlite/retry.store.js +0 -144
  549. package/dist/esm/store/providers/sqlite/sender-key.store.js +0 -203
  550. package/dist/esm/store/providers/sqlite/signal.store.js +0 -353
  551. package/dist/esm/store/providers/sqlite/thread.store.js +0 -72
  552. package/dist/esm/util/base64.js +0 -18
  553. package/dist/esm/util/signal-address.js +0 -5
  554. package/dist/retry/outbound.js +0 -88
  555. package/dist/store/providers/sqlite/BaseSqliteStore.js +0 -41
  556. package/dist/store/providers/sqlite/appstate.store.js +0 -173
  557. package/dist/store/providers/sqlite/auth.store.js +0 -180
  558. package/dist/store/providers/sqlite/connection.js +0 -276
  559. package/dist/store/providers/sqlite/contact.store.js +0 -65
  560. package/dist/store/providers/sqlite/device-list.store.js +0 -159
  561. package/dist/store/providers/sqlite/message.store.js +0 -123
  562. package/dist/store/providers/sqlite/migrations.js +0 -350
  563. package/dist/store/providers/sqlite/participants.store.js +0 -89
  564. package/dist/store/providers/sqlite/retry.store.js +0 -148
  565. package/dist/store/providers/sqlite/sender-key.store.js +0 -207
  566. package/dist/store/providers/sqlite/signal.store.js +0 -357
  567. package/dist/store/providers/sqlite/thread.store.js +0 -76
  568. package/dist/types/appstate/store/sqlite.d.ts +0 -21
  569. package/dist/types/crypto/core/constants.d.ts +0 -1
  570. package/dist/types/crypto/core/encoding.d.ts +0 -11
  571. package/dist/types/retry/outbound.d.ts +0 -4
  572. package/dist/types/store/providers/sqlite/BaseSqliteStore.d.ts +0 -12
  573. package/dist/types/store/providers/sqlite/appstate.store.d.ts +0 -15
  574. package/dist/types/store/providers/sqlite/auth.store.d.ts +0 -10
  575. package/dist/types/store/providers/sqlite/connection.d.ts +0 -10
  576. package/dist/types/store/providers/sqlite/contact.store.d.ts +0 -10
  577. package/dist/types/store/providers/sqlite/device-list.store.d.ts +0 -18
  578. package/dist/types/store/providers/sqlite/message.store.d.ts +0 -11
  579. package/dist/types/store/providers/sqlite/migrations.d.ts +0 -3
  580. package/dist/types/store/providers/sqlite/participants.store.d.ts +0 -13
  581. package/dist/types/store/providers/sqlite/retry.store.d.ts +0 -16
  582. package/dist/types/store/providers/sqlite/sender-key.store.d.ts +0 -25
  583. package/dist/types/store/providers/sqlite/signal.store.d.ts +0 -46
  584. package/dist/types/store/providers/sqlite/thread.store.d.ts +0 -11
  585. package/dist/types/util/base64.d.ts +0 -4
  586. package/dist/types/util/signal-address.d.ts +0 -2
  587. package/dist/util/base64.js +0 -24
  588. package/dist/util/signal-address.js +0 -8
  589. /package/dist/types/transport/node/builders/{accountSync.d.ts → account-sync.d.ts} +0 -0
@@ -4,28 +4,98 @@ import { WaMediaCrypto } from './WaMediaCrypto.js';
4
4
  import { WA_DEFAULTS } from '../protocol/constants.js';
5
5
  import { EMPTY_BYTES, readAllBytes } from '../util/bytes.js';
6
6
  import { toError } from '../util/primitives.js';
7
+ const GOT_OPTIONAL_MODULE = 'got';
8
+ function normalizeHeaderRecord(headers) {
9
+ if (!headers) {
10
+ return {};
11
+ }
12
+ const normalized = {};
13
+ for (const key in headers) {
14
+ normalized[key.toLowerCase()] = headers[key];
15
+ }
16
+ return normalized;
17
+ }
18
+ function asOptionalGotModule(loaded) {
19
+ if (loaded && typeof loaded === 'object') {
20
+ const direct = loaded.stream;
21
+ if (typeof direct === 'function') {
22
+ return loaded;
23
+ }
24
+ const fallback = loaded.default;
25
+ if (fallback &&
26
+ typeof fallback === 'object' &&
27
+ 'stream' in fallback &&
28
+ typeof fallback.stream === 'function') {
29
+ return fallback;
30
+ }
31
+ if (typeof fallback === 'function' && 'stream' in fallback) {
32
+ const maybeStream = fallback.stream;
33
+ if (typeof maybeStream === 'function') {
34
+ return fallback;
35
+ }
36
+ }
37
+ }
38
+ if (typeof loaded === 'function' && 'stream' in loaded) {
39
+ const maybeStream = loaded.stream;
40
+ if (typeof maybeStream === 'function') {
41
+ return loaded;
42
+ }
43
+ }
44
+ return null;
45
+ }
46
+ async function loadOptionalGotModule() {
47
+ try {
48
+ const loaded = await import(GOT_OPTIONAL_MODULE);
49
+ const module = asOptionalGotModule(loaded);
50
+ if (module) {
51
+ return module;
52
+ }
53
+ throw new Error('invalid got module export');
54
+ }
55
+ catch (error) {
56
+ const normalized = toError(error);
57
+ const code = normalized.code;
58
+ const message = normalized.message ?? '';
59
+ const isModuleNotFound = (code === 'ERR_MODULE_NOT_FOUND' || code === 'MODULE_NOT_FOUND') &&
60
+ (message.includes(`'${GOT_OPTIONAL_MODULE}'`) ||
61
+ message.includes(`"${GOT_OPTIONAL_MODULE}"`));
62
+ if (isModuleNotFound) {
63
+ throw new Error('optional dependency "got" is not installed. Install with: npm i got');
64
+ }
65
+ throw normalized;
66
+ }
67
+ }
7
68
  export class WaMediaTransferClient {
8
69
  constructor(options = {}) {
9
70
  this.logger = options.logger;
10
71
  this.defaultHosts = options.defaultHosts ?? DEFAULT_MEDIA_HOSTS;
11
72
  this.defaultTimeoutMs = options.defaultTimeoutMs ?? WA_DEFAULTS.MEDIA_TIMEOUT_MS;
12
73
  this.defaultMaxReadBytes = options.defaultMaxReadBytes;
13
- this.defaultHeaders = options.defaultHeaders ?? {};
74
+ this.defaultHeaders = normalizeHeaderRecord(options.defaultHeaders);
75
+ this.defaultUploadDispatcher = options.defaultUploadDispatcher;
76
+ this.defaultDownloadDispatcher = options.defaultDownloadDispatcher;
77
+ this.defaultUploadAgent = options.defaultUploadAgent;
78
+ this.defaultDownloadAgent = options.defaultDownloadAgent;
79
+ this.gotModulePromise = null;
14
80
  }
15
81
  async downloadStream(request) {
16
82
  const { urls, headers, timeoutMs } = this.resolveTransferRequest(request);
83
+ const dispatcher = request.dispatcher ?? this.defaultDownloadDispatcher;
84
+ const agent = request.agent ?? this.defaultDownloadAgent;
17
85
  this.logger?.debug('media download stream start', {
18
86
  urls: urls.length,
19
87
  timeoutMs
20
88
  });
21
- return this.executeTransfer(urls, timeoutMs, request.signal, {
22
- responseLog: 'media download stream response',
23
- send: (url, signal) => fetch(url, {
24
- method: 'GET',
25
- headers,
26
- signal
27
- })
89
+ const result = await this.fetchWithFallback(urls, timeoutMs, request.signal, (url, signal) => this.transferRequest(url, {
90
+ method: 'GET',
91
+ headers,
92
+ signal
93
+ }, dispatcher, agent));
94
+ this.logger?.trace('media download stream response', {
95
+ url: result.url,
96
+ status: result.status
28
97
  });
98
+ return result;
29
99
  }
30
100
  async downloadBytes(request) {
31
101
  const response = await this.downloadStream(request);
@@ -33,7 +103,9 @@ export class WaMediaTransferClient {
33
103
  if (!response.body) {
34
104
  return EMPTY_BYTES;
35
105
  }
36
- return this.readAllBytesWithLimit(response.body, request.maxBytes);
106
+ return readAllBytes(response.body, {
107
+ maxBytes: request.maxBytes ?? this.defaultMaxReadBytes
108
+ });
37
109
  }
38
110
  async uploadStream(request) {
39
111
  const bodyIsBytes = request.body instanceof Uint8Array;
@@ -43,6 +115,8 @@ export class WaMediaTransferClient {
43
115
  ? String(request.contentLength)
44
116
  : undefined
45
117
  });
118
+ const dispatcher = request.dispatcher ?? this.defaultUploadDispatcher;
119
+ const agent = request.agent ?? this.defaultUploadAgent;
46
120
  const uploadUrls = bodyIsBytes ? urls : urls.slice(0, 1);
47
121
  if (!bodyIsBytes && urls.length > 1) {
48
122
  this.logger?.warn('upload stream fallback disabled for non-replayable body', {
@@ -55,26 +129,28 @@ export class WaMediaTransferClient {
55
129
  timeoutMs,
56
130
  method
57
131
  });
58
- return this.executeTransfer(uploadUrls, timeoutMs, request.signal, {
59
- responseLog: 'media upload stream response',
60
- send: async (url, signal) => {
61
- if (bodyIsBytes) {
62
- return fetch(url, {
63
- method,
64
- headers,
65
- signal,
66
- body: request.body
67
- });
68
- }
69
- return fetch(url, {
132
+ const result = await this.fetchWithFallback(uploadUrls, timeoutMs, request.signal, async (url, signal) => {
133
+ if (bodyIsBytes) {
134
+ return this.transferRequest(url, {
70
135
  method,
71
136
  headers,
72
137
  signal,
73
- body: request.body,
74
- duplex: 'half'
75
- });
138
+ body: request.body
139
+ }, dispatcher, agent);
76
140
  }
141
+ return this.transferRequest(url, {
142
+ method,
143
+ headers,
144
+ signal,
145
+ body: request.body,
146
+ duplex: 'half'
147
+ }, dispatcher, agent);
77
148
  });
149
+ this.logger?.trace('media upload stream response', {
150
+ url: result.url,
151
+ status: result.status
152
+ });
153
+ return result;
78
154
  }
79
155
  async uploadEncrypted(request) {
80
156
  this.logger?.info('media encrypted upload start', {
@@ -89,6 +165,8 @@ export class WaMediaTransferClient {
89
165
  directPath: request.directPath,
90
166
  hosts: request.hosts,
91
167
  headers: request.headers,
168
+ dispatcher: request.dispatcher,
169
+ agent: request.agent,
92
170
  timeoutMs: request.timeoutMs,
93
171
  signal: request.signal,
94
172
  method: request.method,
@@ -109,7 +187,8 @@ export class WaMediaTransferClient {
109
187
  transfer,
110
188
  mediaKey,
111
189
  fileSha256: metadata.fileSha256,
112
- fileEncSha256: metadata.fileEncSha256
190
+ fileEncSha256: metadata.fileEncSha256,
191
+ plaintextLength: metadata.plaintextLength
113
192
  };
114
193
  }
115
194
  async downloadAndDecrypt(request) {
@@ -119,7 +198,9 @@ export class WaMediaTransferClient {
119
198
  const decrypted = await this.downloadAndDecryptStream(request);
120
199
  try {
121
200
  const [plaintext] = await Promise.all([
122
- this.readAllBytesWithLimit(decrypted.plaintext, request.maxBytes),
201
+ readAllBytes(decrypted.plaintext, {
202
+ maxBytes: request.maxBytes ?? this.defaultMaxReadBytes
203
+ }),
123
204
  decrypted.metadata
124
205
  ]);
125
206
  this.logger?.info('media encrypted download completed', {
@@ -155,13 +236,135 @@ export class WaMediaTransferClient {
155
236
  if (!response.body) {
156
237
  return EMPTY_BYTES;
157
238
  }
158
- return this.readAllBytesWithLimit(response.body, maxBytes);
239
+ return readAllBytes(response.body, { maxBytes: maxBytes ?? this.defaultMaxReadBytes });
240
+ }
241
+ async transferRequest(url, init, dispatcher, agent) {
242
+ if (agent) {
243
+ return this.gotWithAgent(url, init, agent);
244
+ }
245
+ return this.fetchWithDispatcher(url, init, dispatcher);
246
+ }
247
+ async fetchWithDispatcher(url, init, dispatcher) {
248
+ const response = !dispatcher
249
+ ? await fetch(url, init)
250
+ : await fetch(url, {
251
+ ...init,
252
+ dispatcher
253
+ });
254
+ return this.toFetchTransferResponse(response);
255
+ }
256
+ toFetchTransferResponse(response) {
257
+ return {
258
+ status: response.status,
259
+ ok: response.ok,
260
+ headers: Object.fromEntries(response.headers.entries()),
261
+ body: response.body
262
+ ? Readable.fromWeb(response.body)
263
+ : null,
264
+ cancel: async () => {
265
+ if (!response.body) {
266
+ return;
267
+ }
268
+ try {
269
+ await response.body.cancel();
270
+ }
271
+ catch {
272
+ // ignore cancel errors from remote resets
273
+ }
274
+ }
275
+ };
276
+ }
277
+ async gotWithAgent(url, init, agent) {
278
+ const got = await this.loadGotModule();
279
+ const urlObj = new URL(url);
280
+ const gotAgent = urlObj.protocol === 'http:'
281
+ ? { http: agent }
282
+ : urlObj.protocol === 'https:'
283
+ ? { https: agent }
284
+ : { http: agent, https: agent };
285
+ return new Promise((resolve, reject) => {
286
+ const request = got.stream(url, {
287
+ method: init.method,
288
+ headers: (init.headers ?? {}),
289
+ body: init.body,
290
+ signal: init.signal,
291
+ throwHttpErrors: false,
292
+ retry: { limit: 0 },
293
+ agent: gotAgent
294
+ });
295
+ const onError = (error) => {
296
+ request.off('response', onResponse);
297
+ reject(toError(error));
298
+ };
299
+ const onResponse = (incoming) => {
300
+ request.off('error', onError);
301
+ resolve(this.toGotTransferResponse(incoming));
302
+ };
303
+ request.once('error', onError);
304
+ request.once('response', onResponse);
305
+ });
306
+ }
307
+ async loadGotModule() {
308
+ if (!this.gotModulePromise) {
309
+ this.gotModulePromise = loadOptionalGotModule().catch((error) => {
310
+ this.gotModulePromise = null;
311
+ throw error;
312
+ });
313
+ }
314
+ return this.gotModulePromise;
315
+ }
316
+ toGotTransferResponse(incoming) {
317
+ if (!incoming || typeof incoming !== 'object') {
318
+ throw new Error('invalid got response object');
319
+ }
320
+ const stream = incoming;
321
+ const status = typeof stream.statusCode === 'number' &&
322
+ Number.isFinite(stream.statusCode) &&
323
+ stream.statusCode >= 100 &&
324
+ stream.statusCode <= 599
325
+ ? stream.statusCode
326
+ : 500;
327
+ const headers = {};
328
+ if (stream.headers && typeof stream.headers === 'object') {
329
+ const input = stream.headers;
330
+ for (const key in input) {
331
+ const value = input[key];
332
+ if (typeof value === 'string') {
333
+ headers[key] = value;
334
+ continue;
335
+ }
336
+ if (Array.isArray(value)) {
337
+ headers[key] = value.join(', ');
338
+ continue;
339
+ }
340
+ if (value !== undefined && value !== null) {
341
+ headers[key] = String(value);
342
+ }
343
+ }
344
+ }
345
+ return {
346
+ status,
347
+ ok: status >= 200 && status < 300,
348
+ headers,
349
+ body: stream,
350
+ cancel: async () => {
351
+ stream.destroy();
352
+ }
353
+ };
159
354
  }
160
355
  resolveTransferRequest(request, extraHeaders) {
161
- const headers = this.mergeHeaders(request.headers);
162
- for (const [key, value] of Object.entries(extraHeaders ?? {})) {
163
- if (value !== undefined) {
164
- headers[key.toLowerCase()] = value;
356
+ const headers = { ...this.defaultHeaders };
357
+ if (request.headers) {
358
+ for (const key in request.headers) {
359
+ headers[key.toLowerCase()] = request.headers[key];
360
+ }
361
+ }
362
+ if (extraHeaders) {
363
+ for (const key in extraHeaders) {
364
+ const value = extraHeaders[key];
365
+ if (value !== undefined) {
366
+ headers[key.toLowerCase()] = value;
367
+ }
165
368
  }
166
369
  }
167
370
  return {
@@ -170,14 +373,6 @@ export class WaMediaTransferClient {
170
373
  timeoutMs: request.timeoutMs ?? this.defaultTimeoutMs
171
374
  };
172
375
  }
173
- async executeTransfer(urls, timeoutMs, signal, options) {
174
- const result = await this.fetchWithFallback(urls, timeoutMs, signal, options.send);
175
- this.logger?.trace(options.responseLog, {
176
- url: result.url,
177
- status: result.response.status
178
- });
179
- return this.toResponse(result.url, result.response);
180
- }
181
376
  async prepareEncryptedUpload(request, mediaKey) {
182
377
  if (request.plaintext instanceof Uint8Array) {
183
378
  const encrypted = await WaMediaCrypto.encryptBytes(request.mediaType, mediaKey, request.plaintext);
@@ -186,7 +381,8 @@ export class WaMediaTransferClient {
186
381
  contentLength: encrypted.ciphertextHmac.byteLength,
187
382
  metadata: Promise.resolve({
188
383
  fileSha256: encrypted.fileSha256,
189
- fileEncSha256: encrypted.fileEncSha256
384
+ fileEncSha256: encrypted.fileEncSha256,
385
+ plaintextLength: request.plaintext.byteLength
190
386
  }),
191
387
  cleanup: async () => undefined
192
388
  };
@@ -219,39 +415,26 @@ export class WaMediaTransferClient {
219
415
  }
220
416
  resolveUrls(url, directPath, hosts) {
221
417
  const resolved = [];
222
- if (url) {
418
+ if (url && resolved.indexOf(url) === -1)
223
419
  resolved.push(url);
224
- }
225
420
  if (directPath) {
226
421
  if (directPath.startsWith('https://') || directPath.startsWith('http://')) {
227
- resolved.push(directPath);
422
+ if (resolved.indexOf(directPath) === -1)
423
+ resolved.push(directPath);
228
424
  }
229
425
  else {
230
426
  const normalizedPath = directPath.startsWith('/') ? directPath : `/${directPath}`;
231
427
  for (const host of hosts ?? this.defaultHosts) {
232
- resolved.push(`https://${host}${normalizedPath}`);
428
+ const candidate = `https://${host}${normalizedPath}`;
429
+ if (resolved.indexOf(candidate) === -1)
430
+ resolved.push(candidate);
233
431
  }
234
432
  }
235
433
  }
236
434
  if (resolved.length === 0) {
237
435
  throw new Error('missing transfer url/directPath');
238
436
  }
239
- return Array.from(new Set(resolved));
240
- }
241
- mergeHeaders(headers) {
242
- const merged = {};
243
- for (const [key, value] of Object.entries(this.defaultHeaders)) {
244
- merged[key.toLowerCase()] = value;
245
- }
246
- for (const [key, value] of Object.entries(headers ?? {})) {
247
- merged[key.toLowerCase()] = value;
248
- }
249
- return merged;
250
- }
251
- readAllBytesWithLimit(stream, maxBytes) {
252
- return readAllBytes(stream, {
253
- maxBytes: maxBytes ?? this.defaultMaxReadBytes
254
- });
437
+ return resolved;
255
438
  }
256
439
  async fetchWithFallback(urls, timeoutMs, signal, send) {
257
440
  let lastError = null;
@@ -262,9 +445,15 @@ export class WaMediaTransferClient {
262
445
  const response = await send(url, abort.signal);
263
446
  const shouldFallback = response.status >= 500 && index < urls.length - 1;
264
447
  if (!shouldFallback) {
265
- return { url, response };
448
+ return {
449
+ url,
450
+ status: response.status,
451
+ ok: response.ok,
452
+ headers: response.headers,
453
+ body: response.body
454
+ };
266
455
  }
267
- await this.cancelWebBody(response.body);
456
+ await response.cancel();
268
457
  this.logger?.warn('transfer fallback to next host', {
269
458
  url,
270
459
  status: response.status
@@ -316,35 +505,6 @@ export class WaMediaTransferClient {
316
505
  }
317
506
  };
318
507
  }
319
- toResponse(url, response) {
320
- return {
321
- url,
322
- status: response.status,
323
- ok: response.ok,
324
- headers: this.headersToRecord(response.headers),
325
- body: response.body
326
- ? Readable.fromWeb(response.body)
327
- : null
328
- };
329
- }
330
- headersToRecord(headers) {
331
- const output = {};
332
- for (const [key, value] of headers.entries()) {
333
- output[key] = value;
334
- }
335
- return output;
336
- }
337
- async cancelWebBody(body) {
338
- if (!body) {
339
- return;
340
- }
341
- try {
342
- await body.cancel();
343
- }
344
- catch {
345
- // ignore cancel errors from remote resets
346
- }
347
- }
348
508
  async drainBody(body) {
349
509
  if (!body) {
350
510
  return;
@@ -16,12 +16,16 @@ export function parseMediaConnResponse(node, nowMs) {
16
16
  throw new Error('media_conn response has invalid ttl');
17
17
  }
18
18
  const expiresAtMs = ttlRaw >= 1000000000 ? ttlRaw * 1000 : nowMs + ttlRaw * 1000;
19
- const hosts = getNodeChildrenByTag(mediaConnNode, WA_NODE_TAGS.HOST)
20
- .map((host) => ({
21
- hostname: host.attrs.hostname ?? '',
22
- isFallback: host.attrs.type === 'fallback'
23
- }))
24
- .filter((host) => host.hostname.length > 0);
19
+ const hosts = [];
20
+ for (const host of getNodeChildrenByTag(mediaConnNode, WA_NODE_TAGS.HOST)) {
21
+ const hostname = host.attrs.hostname;
22
+ if (hostname) {
23
+ hosts.push({
24
+ hostname,
25
+ isFallback: host.attrs.type === 'fallback'
26
+ });
27
+ }
28
+ }
25
29
  if (hosts.length === 0) {
26
30
  throw new Error('media_conn response contains no hosts');
27
31
  }
@@ -1,4 +1,7 @@
1
- export const DEFAULT_MEDIA_HOSTS = ['mmg.whatsapp.net', 'mmg-fallback.whatsapp.net'];
1
+ export const DEFAULT_MEDIA_HOSTS = Object.freeze([
2
+ 'mmg.whatsapp.net',
3
+ 'mmg-fallback.whatsapp.net'
4
+ ]);
2
5
  export const MEDIA_CONN_CACHE_GRACE_MS = 30000;
3
6
  export const MEDIA_HKDF_SIZE = 112;
4
7
  export const IV_SIZE = 16;
@@ -14,5 +17,6 @@ export const MEDIA_UPLOAD_PATHS = Object.freeze({
14
17
  document: '/mms/document',
15
18
  sticker: '/mms/sticker',
16
19
  gif: '/mms/gif',
17
- ptt: '/mms/ptt'
20
+ ptt: '/mms/ptt',
21
+ ptv: '/mms/video'
18
22
  });
@@ -1,8 +1,9 @@
1
1
  import { describeAckNode, isAckOrReceiptNode, isNegativeAckNode, isRetryableNegativeAck } from './ack.js';
2
2
  import { WA_DEFAULTS, WA_MESSAGE_TAGS, WA_MESSAGE_TYPES, WA_NODE_TAGS } from '../protocol/constants.js';
3
- import { parseOptionalInt } from '../transport/stream/parse.js';
3
+ import { buildReceiptNode } from '../transport/node/builders/global.js';
4
4
  import { delay } from '../util/async.js';
5
- import { toError } from '../util/primitives.js';
5
+ import { parseOptionalInt, toError } from '../util/primitives.js';
6
+ const WA_RETRYABLE_PUBLISH_ERROR_RE = /timeout|socket|connection|closed/i;
6
7
  class MessagePublishNackError extends Error {
7
8
  constructor(message, retryable) {
8
9
  super(message);
@@ -102,12 +103,7 @@ export class WaMessageClient {
102
103
  }
103
104
  async sendEncrypted(input) {
104
105
  const node = this.buildEncryptedMessageNode(input);
105
- this.logger.debug('encrypted message sent without waiting for ack', {
106
- to: node.attrs.to,
107
- type: node.attrs.type,
108
- id: node.attrs.id
109
- });
110
- await this.sendNode(node);
106
+ await this.sendMessageNode(node);
111
107
  }
112
108
  buildEncryptedMessageNode(input) {
113
109
  const attrs = {
@@ -117,6 +113,9 @@ export class WaMessageClient {
117
113
  if (input.id) {
118
114
  attrs.id = input.id;
119
115
  }
116
+ if (input.edit) {
117
+ attrs.edit = input.edit;
118
+ }
120
119
  if (input.category) {
121
120
  attrs.category = input.category;
122
121
  }
@@ -136,6 +135,9 @@ export class WaMessageClient {
136
135
  v: WA_MESSAGE_TYPES.ENC_VERSION,
137
136
  type: input.encType
138
137
  };
138
+ if (input.mediatype) {
139
+ encAttrs.mediatype = input.mediatype;
140
+ }
139
141
  if (input.encCount !== undefined && input.encCount > 0) {
140
142
  encAttrs.count = String(Math.trunc(input.encCount));
141
143
  }
@@ -153,6 +155,9 @@ export class WaMessageClient {
153
155
  content: input.deviceIdentity
154
156
  });
155
157
  }
158
+ if (input.metaNode) {
159
+ content.push(input.metaNode);
160
+ }
156
161
  const node = {
157
162
  tag: WA_MESSAGE_TAGS.MESSAGE,
158
163
  attrs,
@@ -161,36 +166,29 @@ export class WaMessageClient {
161
166
  return node;
162
167
  }
163
168
  async sendReceipt(input) {
164
- const attrs = {
169
+ const node = buildReceiptNode({
170
+ kind: 'outbound',
165
171
  to: input.to,
166
172
  id: input.id,
167
- type: input.type ?? 'read'
168
- };
169
- if (input.participant) {
170
- attrs.participant = input.participant;
171
- }
172
- if (input.from) {
173
- attrs.from = input.from;
174
- }
175
- if (input.t) {
176
- attrs.t = input.t;
177
- }
178
- this.logger.debug('sending receipt node', {
179
- to: attrs.to,
180
- id: attrs.id,
181
- type: attrs.type
173
+ type: input.type ?? 'read',
174
+ participant: input.participant,
175
+ recipient: input.recipient,
176
+ category: input.category,
177
+ from: input.from,
178
+ t: input.t,
179
+ peerParticipantPn: input.peerParticipantPn,
180
+ listIds: input.listIds,
181
+ content: input.content ? [...input.content] : undefined
182
182
  });
183
- await this.sendNode({
184
- tag: WA_MESSAGE_TAGS.RECEIPT,
185
- attrs
183
+ this.logger.debug('sending receipt node', {
184
+ to: node.attrs.to,
185
+ id: node.attrs.id,
186
+ type: node.attrs.type
186
187
  });
188
+ await this.sendNode(node);
187
189
  }
188
190
  isRetryablePublishError(error) {
189
- const message = error.message.toLowerCase();
190
- return (message.includes('timeout') ||
191
- message.includes('socket') ||
192
- message.includes('connection') ||
193
- message.includes('closed'));
191
+ return WA_RETRYABLE_PUBLISH_ERROR_RE.test(error.message);
194
192
  }
195
193
  extractAckMetadata(ackNode) {
196
194
  const addressingModeRaw = ackNode.attrs.addressing_mode;
@@ -25,22 +25,22 @@ export function isRetryableNegativeAck(node) {
25
25
  return false;
26
26
  }
27
27
  export function describeAckNode(node) {
28
- const parts = [`tag=${node.tag}`];
28
+ let description = `tag=${node.tag}`;
29
29
  const id = node.attrs.id;
30
30
  const type = node.attrs.type;
31
31
  const ackClass = node.attrs.class;
32
32
  const code = node.attrs.code;
33
33
  if (id) {
34
- parts.push(`id=${id}`);
34
+ description += ` id=${id}`;
35
35
  }
36
36
  if (type) {
37
- parts.push(`type=${type}`);
37
+ description += ` type=${type}`;
38
38
  }
39
39
  if (ackClass) {
40
- parts.push(`class=${ackClass}`);
40
+ description += ` class=${ackClass}`;
41
41
  }
42
42
  if (code) {
43
- parts.push(`code=${code}`);
43
+ description += ` code=${code}`;
44
44
  }
45
- return parts.join(' ');
45
+ return description;
46
46
  }