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
@@ -1,5 +1,6 @@
1
1
  export { MAX_RETRY_ATTEMPTS, RETRY_KEYS_MIN_COUNT, RETRY_OUTBOUND_TTL_MS, RETRY_REASON, RETRY_RECEIPT_VERSION } from './constants.js';
2
2
  export { mapRetryReasonFromError } from './reason.js';
3
- export { parseRetryReceiptRequest } from './parse.js';
4
- export { decodeRetryReplayPayload, encodeRetryReplayPayload, pickRetryStateMax } from './outbound.js';
3
+ export { parseRetryReceiptRequest, pickRetryStateMax } from './parse.js';
4
+ export { decodeRetryReplayPayload, encodeRetryReplayPayload } from './codec.js';
5
5
  export { WaRetryReplayService } from './replay.js';
6
+ export { createOutboundRetryTracker } from './tracker.js';
@@ -1,98 +1,95 @@
1
1
  import { WA_MESSAGE_TAGS, WA_NODE_TAGS } from '../protocol/constants.js';
2
+ import { normalizeDeviceJid } from '../protocol/jid.js';
3
+ import { decodeExactLength, parseUint } from '../signal/api/codec.js';
2
4
  import { SIGNAL_KEY_DATA_LENGTH, SIGNAL_KEY_ID_LENGTH, SIGNAL_REGISTRATION_ID_LENGTH, SIGNAL_SIGNATURE_LENGTH } from '../signal/api/constants.js';
3
- import { decodeNodeContentBase64OrBytes, findNodeChild } from '../transport/node/helpers.js';
4
- import { parseOptionalInt } from '../transport/stream/parse.js';
5
- function parseFixedLengthBytes(value, byteLength, field) {
6
- const out = decodeNodeContentBase64OrBytes(value, field);
7
- if (out.byteLength !== byteLength) {
8
- throw new Error(`${field} must be ${byteLength} bytes`);
9
- }
10
- return out;
11
- }
12
- function parseBigEndianUint(bytes, field) {
13
- if (bytes.byteLength === 0 || bytes.byteLength > 4) {
14
- throw new Error(`${field} has invalid byte length`);
15
- }
16
- const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
17
- if (bytes.byteLength === 1) {
18
- return view.getUint8(0);
19
- }
20
- if (bytes.byteLength === 2) {
21
- return view.getUint16(0);
22
- }
23
- return bytes.byteLength === 3 ? (view.getUint16(0) << 8) | view.getUint8(2) : view.getUint32(0);
24
- }
25
- function parseRetryType(value) {
26
- if (value === 'retry' || value === 'enc_rekey_retry') {
27
- return value;
28
- }
29
- return null;
30
- }
31
- function parseRetryCount(value) {
32
- const parsed = parseOptionalInt(value);
33
- if (parsed === undefined) {
34
- return 0;
35
- }
36
- if (parsed < 0) {
37
- throw new Error('retry count must be >= 0');
5
+ import { decodeNodeContentBase64OrBytes, findNodeChildrenByTags } from '../transport/node/helpers.js';
6
+ import { parseOptionalInt } from '../util/primitives.js';
7
+ const RETRY_STATE_RANK = {
8
+ pending: 0,
9
+ delivered: 1,
10
+ read: 2,
11
+ played: 3,
12
+ ineligible: 4
13
+ };
14
+ function requireNode(node, message) {
15
+ if (!node) {
16
+ throw new Error(message);
38
17
  }
39
- return parsed;
18
+ return node;
40
19
  }
41
- function parseRetryReason(value) {
42
- const parsed = parseOptionalInt(value);
43
- if (parsed === undefined) {
44
- return undefined;
45
- }
46
- if (parsed < 0) {
47
- throw new Error('retry reason must be >= 0');
20
+ function validateRetryReceiptToAttr(to, expectedToJids) {
21
+ if (!to || !expectedToJids || expectedToJids.length === 0) {
22
+ return;
23
+ }
24
+ let normalizedTo;
25
+ try {
26
+ normalizedTo = normalizeDeviceJid(to);
27
+ }
28
+ catch {
29
+ throw new Error('retry receipt has invalid to attr');
30
+ }
31
+ for (let index = 0; index < expectedToJids.length; index += 1) {
32
+ const expected = expectedToJids[index]?.trim();
33
+ if (!expected)
34
+ continue;
35
+ try {
36
+ if (normalizeDeviceJid(expected) === normalizedTo) {
37
+ return;
38
+ }
39
+ }
40
+ catch {
41
+ continue;
42
+ }
48
43
  }
49
- return parsed;
44
+ throw new Error('retry receipt to attr does not match local device');
50
45
  }
51
46
  function parseRetryKeyBundle(node) {
52
47
  if (!node) {
53
48
  return undefined;
54
49
  }
55
- const identityNode = findNodeChild(node, WA_NODE_TAGS.IDENTITY);
56
- const signedKeyNode = findNodeChild(node, WA_NODE_TAGS.SKEY);
57
- if (!identityNode || !signedKeyNode) {
58
- throw new Error('retry keys section missing identity or skey');
59
- }
60
- const signedKeyIdNode = findNodeChild(signedKeyNode, WA_NODE_TAGS.ID);
61
- const signedKeyValueNode = findNodeChild(signedKeyNode, WA_NODE_TAGS.VALUE);
62
- const signedKeySignatureNode = findNodeChild(signedKeyNode, WA_NODE_TAGS.SIGNATURE);
63
- if (!signedKeyIdNode || !signedKeyValueNode || !signedKeySignatureNode) {
64
- throw new Error('retry keys section has incomplete skey');
65
- }
66
- const keyNode = findNodeChild(node, WA_NODE_TAGS.KEY);
67
- const keyIdNode = keyNode ? findNodeChild(keyNode, WA_NODE_TAGS.ID) : undefined;
68
- const keyValueNode = keyNode ? findNodeChild(keyNode, WA_NODE_TAGS.VALUE) : undefined;
69
- if (keyNode && (!keyIdNode || !keyValueNode)) {
70
- throw new Error('retry keys section has incomplete key');
71
- }
72
- const deviceIdentityNode = findNodeChild(node, WA_NODE_TAGS.DEVICE_IDENTITY);
50
+ const [identityNode, signedKeyNode, keyNode, deviceIdentityNode] = findNodeChildrenByTags(node, [WA_NODE_TAGS.IDENTITY, WA_NODE_TAGS.SKEY, WA_NODE_TAGS.KEY, WA_NODE_TAGS.DEVICE_IDENTITY]);
51
+ const identity = requireNode(identityNode, 'retry keys section missing identity or skey');
52
+ const signedKey = requireNode(signedKeyNode, 'retry keys section missing identity or skey');
53
+ const [signedKeyIdNode, signedKeyValueNode, signedKeySignatureNode] = findNodeChildrenByTags(signedKey, [WA_NODE_TAGS.ID, WA_NODE_TAGS.VALUE, WA_NODE_TAGS.SIGNATURE]);
54
+ const signedKeyId = requireNode(signedKeyIdNode, 'retry keys section has incomplete skey');
55
+ const signedKeyValue = requireNode(signedKeyValueNode, 'retry keys section has incomplete skey');
56
+ const signedKeySignature = requireNode(signedKeySignatureNode, 'retry keys section has incomplete skey');
57
+ let keyIdNode;
58
+ let keyValueNode;
59
+ if (keyNode) {
60
+ const keyNodes = findNodeChildrenByTags(keyNode, [WA_NODE_TAGS.ID, WA_NODE_TAGS.VALUE]);
61
+ keyIdNode = keyNodes[0];
62
+ keyValueNode = keyNodes[1];
63
+ }
64
+ const keyId = keyNode ? requireNode(keyIdNode, 'retry keys section has incomplete key') : null;
65
+ const keyValue = keyNode
66
+ ? requireNode(keyValueNode, 'retry keys section has incomplete key')
67
+ : null;
73
68
  return {
74
- identity: parseFixedLengthBytes(identityNode.content, SIGNAL_KEY_DATA_LENGTH, 'retry.keys.identity'),
69
+ identity: decodeExactLength(identity.content, 'retry.keys.identity', SIGNAL_KEY_DATA_LENGTH),
75
70
  deviceIdentity: deviceIdentityNode
76
71
  ? decodeNodeContentBase64OrBytes(deviceIdentityNode.content, 'retry.keys.device-identity')
77
72
  : undefined,
78
- key: keyIdNode && keyValueNode
73
+ key: keyId && keyValue
79
74
  ? {
80
- id: parseBigEndianUint(parseFixedLengthBytes(keyIdNode.content, SIGNAL_KEY_ID_LENGTH, 'retry.keys.key.id'), 'retry.keys.key.id'),
81
- publicKey: parseFixedLengthBytes(keyValueNode.content, SIGNAL_KEY_DATA_LENGTH, 'retry.keys.key.value')
75
+ id: parseUint(decodeExactLength(keyId.content, 'retry.keys.key.id', SIGNAL_KEY_ID_LENGTH), 'retry.keys.key.id'),
76
+ publicKey: decodeExactLength(keyValue.content, 'retry.keys.key.value', SIGNAL_KEY_DATA_LENGTH)
82
77
  }
83
78
  : undefined,
84
79
  skey: {
85
- id: parseBigEndianUint(parseFixedLengthBytes(signedKeyIdNode.content, SIGNAL_KEY_ID_LENGTH, 'retry.keys.skey.id'), 'retry.keys.skey.id'),
86
- publicKey: parseFixedLengthBytes(signedKeyValueNode.content, SIGNAL_KEY_DATA_LENGTH, 'retry.keys.skey.value'),
87
- signature: parseFixedLengthBytes(signedKeySignatureNode.content, SIGNAL_SIGNATURE_LENGTH, 'retry.keys.skey.signature')
80
+ id: parseUint(decodeExactLength(signedKeyId.content, 'retry.keys.skey.id', SIGNAL_KEY_ID_LENGTH), 'retry.keys.skey.id'),
81
+ publicKey: decodeExactLength(signedKeyValue.content, 'retry.keys.skey.value', SIGNAL_KEY_DATA_LENGTH),
82
+ signature: decodeExactLength(signedKeySignature.content, 'retry.keys.skey.signature', SIGNAL_SIGNATURE_LENGTH)
88
83
  }
89
84
  };
90
85
  }
91
- export function parseRetryReceiptRequest(node) {
86
+ export function parseRetryReceiptRequest(node, options) {
92
87
  if (node.tag !== WA_MESSAGE_TAGS.RECEIPT) {
93
88
  return null;
94
89
  }
95
- const receiptType = parseRetryType(node.attrs.type);
90
+ const receiptType = node.attrs.type === 'retry' || node.attrs.type === 'enc_rekey_retry'
91
+ ? node.attrs.type
92
+ : null;
96
93
  if (!receiptType) {
97
94
  return null;
98
95
  }
@@ -101,30 +98,35 @@ export function parseRetryReceiptRequest(node) {
101
98
  if (!stanzaId || !from) {
102
99
  throw new Error('retry receipt is missing id/from attrs');
103
100
  }
104
- const retryNode = findNodeChild(node, 'retry');
105
- if (!retryNode) {
106
- throw new Error('retry receipt is missing retry child');
107
- }
108
- const registrationNode = findNodeChild(node, WA_NODE_TAGS.REGISTRATION);
109
- if (!registrationNode) {
110
- throw new Error('retry receipt is missing registration child');
111
- }
112
- const originalMsgId = retryNode.attrs.id;
101
+ validateRetryReceiptToAttr(node.attrs.to, options?.expectedToJids);
102
+ const [retryNode, registrationNode, keysNode] = findNodeChildrenByTags(node, [
103
+ 'retry',
104
+ WA_NODE_TAGS.REGISTRATION,
105
+ 'keys'
106
+ ]);
107
+ const retry = requireNode(retryNode, 'retry receipt is missing retry child');
108
+ const registrationNodeValue = requireNode(registrationNode, 'retry receipt is missing registration child');
109
+ const originalMsgId = retry.attrs.id;
113
110
  if (!originalMsgId) {
114
111
  throw new Error('retry receipt is missing retry.id');
115
112
  }
116
- const registration = parseFixedLengthBytes(registrationNode.content, SIGNAL_REGISTRATION_ID_LENGTH, 'retry.registration');
113
+ const registration = decodeExactLength(registrationNodeValue.content, 'retry.registration', SIGNAL_REGISTRATION_ID_LENGTH);
117
114
  return {
118
115
  type: receiptType,
119
116
  stanzaId,
120
117
  from,
121
118
  participant: node.attrs.participant,
122
119
  recipient: node.attrs.recipient,
120
+ offline: node.attrs.offline !== undefined,
121
+ isLid: node.attrs.is_lid === 'true',
123
122
  originalMsgId,
124
- retryCount: parseRetryCount(retryNode.attrs.count),
125
- retryReason: parseRetryReason(retryNode.attrs.error ?? node.attrs.error),
126
- t: retryNode.attrs.t ?? node.attrs.t,
127
- regId: parseBigEndianUint(registration, 'retry.registration'),
128
- keyBundle: parseRetryKeyBundle(findNodeChild(node, 'keys'))
123
+ retryCount: parseOptionalInt(retry.attrs.count) ?? 0,
124
+ retryReason: parseOptionalInt(retry.attrs.error ?? node.attrs.error),
125
+ t: retry.attrs.t ?? node.attrs.t,
126
+ regId: parseUint(registration, 'retry.registration'),
127
+ keyBundle: parseRetryKeyBundle(keysNode)
129
128
  };
130
129
  }
130
+ export function pickRetryStateMax(left, right) {
131
+ return RETRY_STATE_RANK[left] >= RETRY_STATE_RANK[right] ? left : right;
132
+ }
@@ -1,29 +1,34 @@
1
1
  import { wrapDeviceSentMessage } from '../message/device-sent.js';
2
2
  import { unpadPkcs7, writeRandomPadMax16 } from '../message/padding.js';
3
3
  import { proto } from '../proto.js';
4
- import { isGroupOrBroadcastJid, normalizeDeviceJid, parseSignalAddressFromJid, splitJid, toUserJid } from '../protocol/jid.js';
5
- import { decodeRetryReplayPayload } from './outbound.js';
4
+ import { isGroupOrBroadcastJid, normalizeDeviceJid, parseJidFull, toUserJid } from '../protocol/jid.js';
5
+ import { decodeRetryReplayPayload } from './codec.js';
6
6
  import { decodeBinaryNode } from '../transport/binary/index.js';
7
7
  import { buildGroupRetryMessageNode } from '../transport/node/builders/message.js';
8
- import { findNodeChild, getNodeChildrenByTag } from '../transport/node/helpers.js';
8
+ import { findNodeChild } from '../transport/node/helpers.js';
9
9
  import { toError } from '../util/primitives.js';
10
10
  export class WaRetryReplayService {
11
11
  constructor(options) {
12
12
  this.options = options;
13
13
  }
14
14
  async resendOutboundMessage(outbound, requesterJid, retryCount) {
15
- const payload = decodeRetryReplayPayload(outbound.replayPayload);
15
+ const payload = outbound.replayPayload instanceof Uint8Array
16
+ ? decodeRetryReplayPayload(outbound.replayPayload)
17
+ : outbound.replayPayload;
18
+ const requesterParsed = parseJidFull(requesterJid);
19
+ const requesterAddress = requesterParsed.address;
20
+ const normalizedRequesterJid = requesterParsed.normalizedJid;
16
21
  if (payload.mode === 'plaintext') {
17
- return this.resendPlaintextPayload(outbound, payload, requesterJid, retryCount);
22
+ return this.resendPlaintextPayload(outbound, payload, requesterJid, requesterAddress, retryCount);
18
23
  }
19
24
  if (payload.mode === 'encrypted') {
20
- return this.resendEncryptedPayload(outbound, payload, requesterJid, retryCount);
25
+ return this.resendEncryptedPayload(outbound, payload, requesterJid, normalizedRequesterJid, retryCount);
21
26
  }
22
- return this.resendOpaquePayload(outbound, payload, requesterJid);
27
+ return this.resendOpaquePayload(outbound, payload, normalizedRequesterJid);
23
28
  }
24
- async resendPlaintextPayload(outbound, payload, requesterJid, retryCount) {
29
+ async resendPlaintextPayload(outbound, payload, requesterJid, requesterAddress, retryCount) {
25
30
  if (isGroupOrBroadcastJid(payload.to)) {
26
- return this.resendGroupPlaintextPayload(outbound, payload, requesterJid);
31
+ return this.resendGroupPlaintextPayload(outbound, payload, requesterJid, requesterAddress, retryCount);
27
32
  }
28
33
  let payloadUserJid;
29
34
  let requesterUserJid;
@@ -37,8 +42,8 @@ export class WaRetryReplayService {
37
42
  if (payloadUserJid !== requesterUserJid) {
38
43
  return 'ineligible';
39
44
  }
40
- const encrypted = await this.signalProtocol.encryptMessage(parseSignalAddressFromJid(requesterJid), payload.plaintext);
41
- await this.messageClient.sendEncrypted({
45
+ const encrypted = await this.options.signalProtocol.encryptMessage(requesterAddress, payload.plaintext);
46
+ await this.options.messageClient.sendEncrypted({
42
47
  to: requesterJid,
43
48
  encType: encrypted.type,
44
49
  ciphertext: encrypted.ciphertext,
@@ -48,15 +53,15 @@ export class WaRetryReplayService {
48
53
  });
49
54
  return 'resent';
50
55
  }
51
- async resendGroupPlaintextPayload(outbound, payload, requesterJid) {
56
+ async resendGroupPlaintextPayload(outbound, payload, requesterJid, requesterAddress, retryCount) {
52
57
  const plaintext = (await this.maybeWrapGroupRetryPlaintextForSelfDevice(payload, requesterJid)) ??
53
58
  payload.plaintext;
54
- const encrypted = await this.signalProtocol.encryptMessage(parseSignalAddressFromJid(requesterJid), plaintext);
59
+ const encrypted = await this.options.signalProtocol.encryptMessage(requesterAddress, plaintext);
55
60
  let deviceIdentity;
56
61
  if (encrypted.type === 'pkmsg') {
57
- const signedIdentity = this.getCurrentSignedIdentity();
62
+ const signedIdentity = this.options.getCurrentSignedIdentity();
58
63
  if (!signedIdentity) {
59
- this.logger.warn('retry request rejected: missing signed identity for pkmsg group retry');
64
+ this.options.logger.warn('retry request rejected: missing signed identity for pkmsg group retry');
60
65
  return 'ineligible';
61
66
  }
62
67
  deviceIdentity = proto.ADVSignedDeviceIdentity.encode(signedIdentity).finish();
@@ -66,22 +71,23 @@ export class WaRetryReplayService {
66
71
  type: payload.type,
67
72
  id: outbound.messageId,
68
73
  requesterJid,
69
- addressingMode: splitJid(requesterJid).server === 'lid' ? 'lid' : 'pn',
74
+ addressingMode: requesterAddress.server === 'lid' ? 'lid' : 'pn',
70
75
  encType: encrypted.type,
71
76
  ciphertext: encrypted.ciphertext,
77
+ retryCount,
72
78
  deviceIdentity
73
79
  });
74
- await this.messageClient.sendMessageNode(retryNode);
80
+ await this.options.messageClient.sendMessageNode(retryNode);
75
81
  return 'resent';
76
82
  }
77
- async resendEncryptedPayload(outbound, payload, requesterJid, retryCount) {
83
+ async resendEncryptedPayload(outbound, payload, requesterJid, normalizedRequesterJid, retryCount) {
78
84
  if (payload.encType === 'skmsg') {
79
85
  return 'ineligible';
80
86
  }
81
- if (normalizeDeviceJid(payload.to) !== normalizeDeviceJid(requesterJid)) {
87
+ if (normalizeDeviceJid(payload.to) !== normalizedRequesterJid) {
82
88
  return 'ineligible';
83
89
  }
84
- await this.messageClient.sendEncrypted({
90
+ await this.options.messageClient.sendEncrypted({
85
91
  to: requesterJid,
86
92
  encType: payload.encType,
87
93
  ciphertext: payload.ciphertext,
@@ -92,8 +98,11 @@ export class WaRetryReplayService {
92
98
  });
93
99
  return 'resent';
94
100
  }
95
- async resendOpaquePayload(outbound, payload, requesterJid) {
101
+ async resendOpaquePayload(outbound, payload, normalizedRequesterJid) {
96
102
  const decoded = decodeBinaryNode(payload.node);
103
+ if (!this.isOpaqueReplayCompatible(decoded, normalizedRequesterJid)) {
104
+ return 'ineligible';
105
+ }
97
106
  const replayNode = decoded.attrs.id === outbound.messageId
98
107
  ? decoded
99
108
  : {
@@ -103,10 +112,7 @@ export class WaRetryReplayService {
103
112
  id: outbound.messageId
104
113
  }
105
114
  };
106
- if (!this.isOpaqueReplayCompatible(replayNode, requesterJid)) {
107
- return 'ineligible';
108
- }
109
- await this.messageClient.sendMessageNode(replayNode);
115
+ await this.options.messageClient.sendMessageNode(replayNode);
110
116
  return 'resent';
111
117
  }
112
118
  async maybeWrapGroupRetryPlaintextForSelfDevice(payload, requesterJid) {
@@ -120,7 +126,7 @@ export class WaRetryReplayService {
120
126
  return writeRandomPadMax16(proto.Message.encode(wrapped).finish());
121
127
  }
122
128
  catch (error) {
123
- this.logger.warn('retry request failed to wrap deviceSent payload for self requester', {
129
+ this.options.logger.warn('retry request failed to wrap deviceSent payload for self requester', {
124
130
  requester: requesterJid,
125
131
  to: payload.to,
126
132
  message: toError(error).message
@@ -140,38 +146,35 @@ export class WaRetryReplayService {
140
146
  }
141
147
  return false;
142
148
  }
143
- get logger() {
144
- return this.options.logger;
145
- }
146
- get messageClient() {
147
- return this.options.messageClient;
148
- }
149
- get signalProtocol() {
150
- return this.options.signalProtocol;
151
- }
152
- getCurrentSignedIdentity() {
153
- return this.options.getCurrentSignedIdentity();
154
- }
155
- isOpaqueReplayCompatible(node, requesterJid) {
156
- const requester = normalizeDeviceJid(requesterJid);
149
+ isOpaqueReplayCompatible(node, normalizedRequesterJid) {
157
150
  const participantsNode = findNodeChild(node, 'participants');
158
151
  if (participantsNode) {
159
- const toNodes = getNodeChildrenByTag(participantsNode, 'to');
160
- if (toNodes.length !== 1) {
161
- return false;
152
+ const participantsContent = Array.isArray(participantsNode.content)
153
+ ? participantsNode.content
154
+ : [];
155
+ let participantNode;
156
+ let participantCount = 0;
157
+ for (let index = 0; index < participantsContent.length; index++) {
158
+ const child = participantsContent[index];
159
+ if (child.tag !== 'to')
160
+ continue;
161
+ participantCount++;
162
+ if (participantCount > 1)
163
+ return false;
164
+ participantNode = child;
162
165
  }
163
- const participantJid = toNodes[0].attrs.jid;
164
- if (!participantJid) {
166
+ if (participantCount !== 1 || !participantNode)
165
167
  return false;
166
- }
167
- return normalizeDeviceJid(participantJid) === requester;
168
+ const participantJid = participantNode.attrs.jid;
169
+ if (!participantJid)
170
+ return false;
171
+ return normalizeDeviceJid(participantJid) === normalizedRequesterJid;
168
172
  }
169
173
  if (node.attrs.participant) {
170
- return normalizeDeviceJid(node.attrs.participant) === requester;
171
- }
172
- if (node.attrs.to) {
173
- return normalizeDeviceJid(node.attrs.to) === requester;
174
+ return normalizeDeviceJid(node.attrs.participant) === normalizedRequesterJid;
174
175
  }
176
+ if (node.attrs.to)
177
+ return normalizeDeviceJid(node.attrs.to) === normalizedRequesterJid;
175
178
  return false;
176
179
  }
177
180
  }
@@ -0,0 +1,94 @@
1
+ import { isGroupOrBroadcastJid, normalizeDeviceJid } from '../protocol/jid.js';
2
+ import { encodeRetryReplayPayload } from './codec.js';
3
+ import { RETRY_OUTBOUND_TTL_MS } from './constants.js';
4
+ import { toError } from '../util/primitives.js';
5
+ export function createOutboundRetryTracker(options) {
6
+ const { retryStore, logger } = options;
7
+ const retryTtlMs = retryStore.getTtlMs?.() ?? RETRY_OUTBOUND_TTL_MS;
8
+ const supportsRawReplayPayload = retryStore.supportsRawReplayPayload?.() ?? false;
9
+ const normalizeEligibleRequesterDeviceJids = (values) => {
10
+ if (!values || values.length === 0) {
11
+ return undefined;
12
+ }
13
+ const deduped = new Set();
14
+ for (let index = 0; index < values.length; index += 1) {
15
+ const raw = values[index]?.trim();
16
+ if (!raw) {
17
+ continue;
18
+ }
19
+ try {
20
+ deduped.add(normalizeDeviceJid(raw));
21
+ }
22
+ catch {
23
+ continue;
24
+ }
25
+ }
26
+ if (deduped.size === 0) {
27
+ return undefined;
28
+ }
29
+ return Array.from(deduped);
30
+ };
31
+ const safeUpsertRetryOutboundRecord = async (record) => {
32
+ try {
33
+ await retryStore.upsertOutboundMessage(record);
34
+ }
35
+ catch (error) {
36
+ logger.warn('failed to persist retry outbound message record', {
37
+ messageId: record.messageId,
38
+ to: record.toJid,
39
+ mode: record.replayMode,
40
+ message: toError(error).message
41
+ });
42
+ return false;
43
+ }
44
+ return true;
45
+ };
46
+ return {
47
+ track: async (hint, publish) => {
48
+ const nowMs = Date.now();
49
+ const replayMode = hint.replayPayload.mode;
50
+ const resolvedToJid = hint.toJid ?? (replayMode === 'opaque_node' ? '' : hint.replayPayload.to);
51
+ const replayPayload = supportsRawReplayPayload
52
+ ? hint.replayPayload
53
+ : encodeRetryReplayPayload(hint.replayPayload);
54
+ let eligibleRequesterDeviceJids = normalizeEligibleRequesterDeviceJids(hint.eligibleRequesterDeviceJids);
55
+ if (!eligibleRequesterDeviceJids &&
56
+ resolvedToJid &&
57
+ !isGroupOrBroadcastJid(resolvedToJid)) {
58
+ try {
59
+ eligibleRequesterDeviceJids = [normalizeDeviceJid(resolvedToJid)];
60
+ }
61
+ catch {
62
+ eligibleRequesterDeviceJids = undefined;
63
+ }
64
+ }
65
+ const createRetryOutboundRecord = (messageId, updatedAtMs, expiresAtMs) => ({
66
+ messageId,
67
+ toJid: resolvedToJid,
68
+ participantJid: hint.participantJid,
69
+ recipientJid: hint.recipientJid,
70
+ eligibleRequesterDeviceJids,
71
+ deliveredRequesterDeviceJids: [],
72
+ messageType: hint.type,
73
+ replayMode,
74
+ replayPayload,
75
+ state: 'pending',
76
+ createdAtMs: nowMs,
77
+ updatedAtMs,
78
+ expiresAtMs
79
+ });
80
+ const result = await publish();
81
+ const persistedMessageId = result.id.trim();
82
+ if (!persistedMessageId) {
83
+ logger.warn('retry outbound record skipped: publish returned empty message id', {
84
+ to: resolvedToJid,
85
+ mode: replayMode
86
+ });
87
+ return result;
88
+ }
89
+ const persistedNowMs = Date.now();
90
+ await safeUpsertRetryOutboundRecord(createRetryOutboundRecord(persistedMessageId, persistedNowMs, persistedNowMs + retryTtlMs));
91
+ return result;
92
+ }
93
+ };
94
+ }